On Jul 8, 4:57 pm, Frantisek Sodomka <fsodo...@gmail.com> wrote: > So far it seems that vectors win in Clojure: > > (timings 3e5 > (let [v (vector 1 2 3) a (nth v 0) b (nth v 1) c (nth v 2)] (+ a b > c)) > (let [lst (list 1 2 3) a (nth lst 0) b (nth lst 1) c (nth lst 2)] (+ > a b c))) > > => > 680.63 ms 83.6% 1.2x (let [v (vector 1 2 3) a (nth v 0) b (nth > v 1) c (nth v 2)] (+ a b c)) > 813.79 ms 100.0% 1.0x (let [lst (list 1 2 3) a (nth lst 0) b > (nth lst 1) c (nth lst 2)] (+ a b c)) > > Frantisek > > On Jul 8, 7:29 pm, John Harrop <jharrop...@gmail.com> wrote: > > > Interesting. How are these timings affected if you add in the time taken to > > pack the list or vector in the first place, though? I have the feeling it > > may be slightly cheaper to unpack a vector, but noticeably cheaper to pack a > > list... > >
I did some playing and it seems that the x-factor is really whether or not the array access function is in-lined into the code. I made a few tweaks to the source code so that the destructuring bind is able to rewrite the code with the 2-ary version and avoid rebinding overhead. I'll post it in reply to this. Here are some results I collected: (I like your 'timings' macro, by the way). (let [v [1 2 3] lst '(1 2 3)] (timings 1e7 (let [[a b c] v] a b c) (let [[a b c] #^{:length 3} v] a b c) (let [[a b c] #^{:tag :vector :length 3} v] a b c) (let [[a b c] #^{:length 3} [1 2 3]] a b c) (let [a (v 0) b (v 1) c (v 2)] a b c) (let [a (nth v 0) b (nth v 1) c (nth v 2)] a b c) (let [a (first v) b (second v) c (first (rest (rest v)))] a b c) (let [x (first v) r1 (rest v) y (first r1) r2 (rest r1) z (first r2)] x y z) (let [[a b c] lst] a b c) ;; (let [a (lst 0) b (lst 1) c (lst 2)] [a b c]) (let [a (nth lst 0) b (nth lst 1) c (nth lst 2)] a b c) (let [a (first lst) b (second lst) c (first (rest (rest lst)))] a b c) (let [x (first lst) r1 (rest lst) y (first r1) r2 (rest r1) z (first r2)] x y z))) --- no inlining of 3-ary version (inlines 2ary version as normal), rewriting to 2-ary version dependant on :length :tag metadata and 4650.19 ms 34.2% 2.9x (let [[a b c] v] a b c) ;;nothing 3675.41 ms 27.0% 3.7x (let [[a b c] v] a b c) ;;length 3414.78 ms 25.1% 4.0x (let [[a b c] v] a b c) ;; tag length 13606.68 ms 100.0% 1.0x (let [[a b c] [1 2 3]] a b c) 3459.74 ms 25.4% 3.9x (let [a (v 0) b (v 1) c (v 2)] a b c) 3551.73 ms 26.1% 3.8x (let [a (nth v 0) b (nth v 1) c (nth v 2)] a b c) 9810.52 ms 72.1% 1.4x (let [a (first v) b (second v) c (first (rest (rest v)))] a b c) 9234.34 ms 67.9% 1.5x (let [x (first v) r1 (rest v) y (first r1) r2 (rest r1) z (first r2)] x y z) 9519.99 ms 70.0% 1.4x (let [[a b c] lst] a b c) 7131.29 ms 52.4% 1.9x (let [a (nth lst 0) b (nth lst 1) c (nth lst 2)] a b c) 7665.99 ms 56.3% 1.8x (let [a (first lst) b (second lst) c (first (rest (rest lst)))] a b c) 7490.44 ms 55.0% 1.8x (let [x (first lst) r1 (rest lst) y (first r1) r2 (rest r1) z (first r2)] x y z) --- inlining 3ary version, rewriting dependant on :length and :tag. 3230.53 ms 24.6% 4.1x (let [[a b c] v] a b c) ;;nothing 3557.94 ms 27.1% 3.7x (let [[a b c] v] a b c) ;;length 3287.01 ms 25.1% 4.0x (let [[a b c] v] a b c) ;;tag +length 13116.50 ms 100.0% 1.0x (let [[a b c] [1 2 3]] a b c) 3287.39 ms 25.1% 4.0x (let [a (v 0) b (v 1) c (v 2)] a b c) 3615.61 ms 27.6% 3.6x (let [a (nth v 0) b (nth v 1) c (nth v 2)] a b c) 10634.64 ms 81.1% 1.2x (let [a (first v) b (second v) c (first (rest (rest v)))] a b c) 10147.02 ms 77.4% 1.3x (let [x (first v) r1 (rest v) y (first r1) r2 (rest r1) z (first r2)] x y z) 8476.63 ms 64.6% 1.5x (let [[a b c] lst] a b c) 7106.42 ms 54.2% 1.8x (let [a (nth lst 0) b (nth lst 1) c (nth lst 2)] a b c) 8172.17 ms 62.3% 1.6x (let [a (first lst) b (second lst) c (first (rest (rest lst)))] a b c) 8031.60 ms 61.2% 1.6x (let [x (first lst) r1 (rest lst) y (first r1) r2 (rest r1) z (first r2)] x y z) I'll post the rather small tweaks in a response to this post. Please note that i was playing with a (month old) alpha 1.1 version of clojure.core, so I am not sure what the differences would be between it and a current version. I think the most interesting part is that you can get pretty much the same effect by just telling it to inline the 3ary version of nth. (Although it is a multi function, so it seems there is still some sort of funcall overhead). --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---