Fork me on GitHub
#clojure-europe
<
2020-12-01
>
dharrigan06:12:12

Good Morning!

plexus06:12:15

Good morning!

otfrom09:12:54

awesome. thx!

raymcdermott10:12:46

morning ... mood

borkdude10:12:50

Morning! Welcome to join the London Clojurians meetup tonight, where'll be showing some internals of babashka and sci. https://www.meetup.com/London-Clojurians/events/274014078/

ordnungswidrig10:12:00

The view from my shower :rolling_on_the_floor_laughing: 🙈

dharrigan10:12:22

I call that a snow-day. Grab a snowboard/skis and hit those slopes!

borkdude10:12:46

I revisited some code in sci and thought: what the hell did I do here. Perf gain my ass. Then I checked it:

user> (time (dotimes [i 1000000] (let [expr '(1 2 3) cond (first expr) expr (rest expr) then (first expr) expr (rest expr) else (first expr)] [cond then else])))
"Elapsed time: 119.671576 msecs"
nil
user> (time (dotimes [i 1000000] (let [[cond then else] '(1 2 3)] [cond then else])))
"Elapsed time: 744.034037 msecs"
nil
Yeah, indeed, that's a perf gain. Sequential destructuring costs more than manually writing things with first and rest. 🤷

dominicm11:12:06

I thought destructuring expanded to the same thing

borkdude11:12:12

Destructuring expands to nth calls on the vector

borkdude11:12:48

user=> (destructure '[[cond then else] '(1 2 3)])
[vec__34112 (quote (1 2 3)) cond (clojure.core/nth vec__34112 0 nil) then (clojure.core/nth vec__34112 1 nil) else (clojure.core/nth vec__34112 2 nil)]

borkdude11:12:39

huh, no, it expands to nth calls on the thing you destructure on, and nth for lists isn't so perfect for this since that's an O(n) operation

borkdude11:12:49

user=> (time (dotimes [i 1000000] (let [[cond then else] [1 2 3]] [cond then else])))
"Elapsed time: 65.380112 msecs"
nil
user=> (time (dotimes [i 1000000] (let [[cond then else] (list 1 2 3)] [cond then else])))
"Elapsed time: 1181.079782 msecs"

borkdude12:12:20

But the cost of turning a list into a vector should also be taken into account:

user=> (time (dotimes [i 1000000] (let [[cond then else] (vec (list 1 2 3))] [cond then else])))
"Elapsed time: 572.364397 msecs"
so all in all, doing first + rest might be the optimal destructuring for lists

dominicm14:12:10

So it has to reiterate the list each time. Interesting. That seems like an opportunity for destructure to get smarter.