Rich Hickey:

> You might find this interesting:
> http://clojure.org/transients
> It supports using the exact same immutable data structures in/out of your 
> (externally pure) function, as well as the exact same functional "shape" of 
> your code when using transients (roughly, mutables) internally.

Yes, it's interesting and cute, thank you for the link.

D2 too is leading in that direction, allowing mutables and imperative code 
inside pure functions. (That's also why I have asked Don to fix pure/notpure 
functions inside pure functions, so now inside pure functions you can have 
complex stuff (inner functions are a bit slower, but probably that's often 
acceptable)).

Near the end of that page there's written:

>(time (def v (vrange 1000000)))
"Elapsed time: 297.444 msecs"

(time (def v2 (vrange2 1000000)))
"Elapsed time: 34.428 msecs"

Oh, yeah, transients are fast!<

34 ms is the timing with transients. The problem is that "fast" is almost 
meaningless. When you give a timing you have to always give ways to perform an 
absolute comparison too, relative comparisons aren't enough. When you show 
Clojure timings you have to specify the CPU and give timings for equivalent C 
and Java code.

For example on a ~2GHz Celeron in D that allocation + initialization loop takes 
about 7.3 ms with DMD. If you use memory from the C heap (avoiding the initial 
useless clearing of the array of integers) that code runs in about 3.6 ms. 
Almost ten times faster than that "fast" Clojure version.

(I'd like the D compiler to recognize the basic situations where the code 
clears a vector of values that are then immediately fully initialized, and 
avoid the clearing, to save some time. It's a very basic optimization, it's a 
very common situation, and avoids the programmer to manually write such boring 
optimization. Thank you.)

Bye,
bearophile

Reply via email to