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
-~----------~----~----~----~------~----~------~--~---

Reply via email to