[CLJ-1010] A left-to-right-variant of `comp` Created: 11/Jun/12 Updated: 03/Sep/13
The function composition function `comp` is quite inefficient in cases like `(apply comp large-seq-of-fns)`, because its arity-greater-than-3 version reverses the seq.
I would be great if there was an alternative `comp*` (or whatever) function which is just like `comp` but composes left-to-right.
|Comment by Tassilo Horn [ 11/Jun/12 5:16 AM ]|
Here's an implementation.
|Comment by Tassilo Horn [ 11/Jun/12 12:41 PM ]|
There's something strange with my patch. The creation of a composition of a huge seq of functions is much faster with `comp*` than with `comp`, which is expected, because the seq doesn't need to be reversed.
The strange thing however is that the compositions created with `comp` evaluate about 10-20% faster than those created with `comp*` although the arbitrary-arity version of `comp` is defined in terms of `comp*`: `(apply comp* (reverse (list* f1 f2 f3 fs)))`.
For some benchmarking details, see: https://groups.google.com/d/msg/clojure/MizwTxHwLE4/hGLrMfetlP8J
|Comment by Tassilo Horn [ 14/Jun/12 2:32 AM ]|
Here's some benchmark:
|Comment by Tassilo Horn [ 14/Jun/12 3:40 AM ]|
Ok, I've tracked down the performance difference. This comes from the fact that `reverse` creates a clojure.lang.PersistentList which can be iterated much faster than a (fully realized) LazySeq. If you provide your fncoll in `(apply comp* fncoll)` as vector or list, the application of the created composition is as fast as for `comp`.
So for me, the patch is good and makes sense.