Please bear with me, this is a long question!
To explain, I'm a scientist considering switching from C++ to D, but before I do, I need to ensure that I can: - achieve execution speeds comparable to C++ (for the same accuracy; I can accept a slight slowdown, call it 30%, to get a few more digits (which I typically don't need)) - easily perform all standard mathematical operations on complex numbers - (many other things not relevant here: memory use, parallelization, etc).

In the two files linked below, I compare execution speed/accuracy between D and C++ when using log on complex variables:

https://www.dropbox.com/s/hfw7nkwg25mk37u/test_cx.d?dl=0
https://www.dropbox.com/s/hfw7nkwg25mk37u/test_cx.d?dl=0

The idea is simple: let a complex variable be uniformly distributed around the unit circle. Summing the logs should give zero.

In the D code, I've defined an "own" version of the log, log_cx, since std.complex (tragically!) does not provide this function (and many others, see recent threads https://forum.dlang.org/post/dewzhtnpqkaqkzxwp...@forum.dlang.org and https://forum.dlang.org/thread/lsnuevdefktulxlto...@forum.dlang.org, and issue https://issues.dlang.org/show_bug.cgi?id=18571).

First, speed/accuracy (times for 1M points in all cases):
D:
dmd, no flags:
Complex!real: re, im (should be 0): -9.24759400999786151942e-15 6.26324079407839123978e-14
time for 1000000 pts: 190 ms, 508 μs, and 9 hnsecs
Complex!double: re, im (should be 0): -1.96986871259241524967e-12 5.46260919029144254022e-09
time for 1000000 pts: 455 ms, 888 μs, and 7 hnsecs

dmd -release -inline -O:
Complex!real: re, im (should be 0): -9.24759400999786151942e-15 6.26324079407839123978e-14
time for 1000000 pts: 175 ms, 352 μs, and 3 hnsecs
Complex!double: re, im (should be 0): -4.23880765557105362133e-14 5.46260919029144254022e-09
time for 1000000 pts: 402 ms, 965 μs, and 7 hnsecs

ldc2, no flags:
Complex!real: re, im (should be 0): -9.24759400999786151942e-15 6.26324079407839123978e-14
time for 1000000 pts: 184 ms, 353 μs, and 9 hnsecs
Complex!double: re, im (should be 0): -1.96986871259241524967e-12 5.46260919029144254022e-09
time for 1000000 pts: 436 ms, 526 μs, and 8 hnsecs

ldc2 -release -O:
Complex!real: re, im (should be 0): -9.24759400999786151942e-15 6.26324079407839123978e-14
time for 1000000 pts: 108 ms and 966 μs
Complex!double: re, im (should be 0): -1.96986871259241524967e-12 5.46260919029144254022e-09
time for 1000000 pts: 330 ms, 421 μs, and 8 hnsecs

As expected accuracy with Complex!real is about 4 digits better, and the best combo is ldc2 with flags.

Now C++:
GCC 7.1.0, -O3:
complex<double>: re, im (should be 0): (8.788326118779445e-13,1.433519814600731e-11)
time for 1000000 pts: 0.042751 seconds.

Apple LLVM version 9.0.0 (clang-900.0.39.2), -O3:
complex<double>: re, im (should be 0): (-3.0160318686967e-12,1.433519814600731e-11)
time for 1000000 pts: 0.038715 seconds.

So simple C++ is thrice as fast as the best-achieved D I managed.

Now for my questions:
- I would expect the D `Complex!double` case to work faster than the `real` one. Why is it the other way around? [I can accept (and use) D with Complex!real running 1/3 the speed of C++ (but with increased accuracy), but I'd also love to be able to run D with `Complex!double` at C++ speeds, since the tradeoff might be worth it for some calculations] - what is the best way to correct the unfortunate (to be polite) omission of many standard mathematical functions from std.complex? [if I may be frank, this is a real pain for us scientists] There exists https://gist.github.com/Biotronic/17af645c2c9b7913de1f04980cd22b37 but can this be integrated (after improvements) in the language, or should I (re)build my own? - for my education, why was the decision made to go from the built-in types `creal` etc to the `Complex` type?

[related questions:

Reply via email to