Francis,

The times you got also heavily depend on the actual side-effect function, 
which in this case is much faster when called with one arg, instead of with 
varargs, that fluokitten need here.

If we give fluokitten a function that does not create a sequence for 
multiple arguments, it is much faster than the fastest example that you 
give (although it does not do any numerical optimizations).

For example, your code runs the following times on my machine (measured by 
criterium):

(def v1 (vec (range 10000)))

(def v2 (vec (range 10000)))

(def side-effect (constantly nil))

(defn side-effect-2 [a b] nil)

(with-progress-reporting (quick-bench  (foldmap op nil side-effect-2 v1 v2
)))

Execution time mean : 290.822794 µs

(with-progress-reporting (quick-bench  (run! side-effect (mapv vector v1 v2
))))

Execution time mean : 847.292924 µs

(defn side-effect-3 [a] nil)

(with-progress-reporting (quick-bench  (run! side-effect-3 (mapv vector v1 
v2))))

 Execution time mean : 847.554524 µs

So, in your previous example, all the "normal" clojure code seems to be 
optimally written, but fluokitten was handicapped by the side-effect's use 
of varargs for only 2 arguments. When side-effects is written "better, 
fluokitten is 3 times faster than the fastest "vanilla" solution (of those 
mentioned).

Of course, most of the time in real life, except with numerics, the 
side-effect function would be much slower than in this example, so I expect 
all of those examples to have similar performance. The actual issue becomes 
memory allocation, and it seems to me that marsi0 asked the question with 
this in mind.

On Saturday, September 24, 2016 at 4:59:35 PM UTC+2, Francis Avila wrote:
>
> BTW I noticed that sequence got hotter and eventually became the fastest, 
> but it took many more runs:
>
> (time (dorun (sequence (map side-effect) col1 col2)))
> "Elapsed time: 31.321698 msecs"
> => nil
> (time (dorun (sequence (map side-effect) col1 col2)))
> "Elapsed time: 15.492247 msecs"
> => nil
> (time (dorun (sequence (map side-effect) col1 col2)))
> "Elapsed time: 10.9549 msecs"
> => nil
> (time (dorun (sequence (map side-effect) col1 col2)))
> "Elapsed time: 9.122967 msecs"
> => nil
> (time (dorun (sequence (map side-effect) col1 col2)))
> "Elapsed time: 18.056823 msecs"
> => nil
> (time (dorun (sequence (map side-effect) col1 col2)))
> "Elapsed time: 9.381068 msecs"
> => nil
>
>
> This is likely close to the theoretical maximum (using loop+recur plus a 
> mutable iterator over multiple colls). The only thing faster would get rid 
> of the iterator, which would require using a memory-indexable data 
> structure like an array, and now you are in core.matrix and neanderthal 
> territory.
>
>
> On Thursday, September 22, 2016 at 11:02:09 PM UTC-5, Mars0i wrote:
>>
>> This is almost the same as an issue I raised in this group over a year 
>> and a half ago, here 
>> <https://groups.google.com/forum/#!msg/clojure/bn5QmxQF7vI/vO1XLSyPXC8J;context-place=forum/clojure>.
>>   
>> I suggested that Clojure should include function with map's syntax but that 
>> was executed only for side-effects, without constructing sequences.  No one 
>> else was interested--no problem.   It's still bugging me.
>>
>> It's not map syntax that I care about at this point.  What's bugging me 
>> is that there's no standard, built-in way to process multiple sequences for 
>> side effects without (a) constructing unnecessary sequences or (b) rolling 
>> my own function with loop/recur or something else.
>>
>> If I want to process multiple sequences for side-effects in the the way 
>> that 'for' does, Clojure gives me 'doseq'.  Beautiful.  I can operate on 
>> the cross product of the sequences, or filter them in various ways.
>>
>> If I want to process multiple sequences by applying an n-ary function to 
>> the first element of each of n sequences, then to the second element of 
>> each sequence, and so on, I can use 'map' or 'mapv', but that means 
>> constructing unnecessary collections.
>>
>> Or I can splice my n sequences together, and make a single sequence of 
>> n-tuples, and use doseq to process it.  (There's an example like this on 
>> the doseq doc page.)  Or I can process such a sequence with 'reduce'.  More 
>> unnecessary collections, though.
>>
>> Or I can use 'dotimes', and index into each of the collections, which is 
>> OK if they're vectors, but ... ugh. why?
>>
>> Or I can construct my own function using first and rest or first and next 
>> on each of my sequences, via loop/recur, for example.   But that seems odd 
>> to me.  
>>
>> Isn't this a common use case?  Is processing multiple sequences for 
>> side-effects with corresponding elements in each application so unusual?  
>> (Am I the only one?)  Isn't it odd that we have doseq and map but nothing 
>> that processes multiple sequences for side-effects, in sequence, rather 
>> than as a cross-product?  
>>
>> (I admit that in my current use case, the sequences are small, so 
>> creating a sequence of n-tuples would have only a trivial cost.  It just 
>> bugs me, though. :-)
>>
>> I'd still be OK with something that had a map-like syntax, but my current 
>> inclination is that it would be better for such a function to have 
>> doseq-style syntax.  The name might be derived from "doseq"--maybe 
>> "doseq*". 
>>
>> (I'd be willing to suggest this in a JIRA ticket, but that doesn't seem 
>> reasonable unless there's a call for something like this from more than one 
>> person.)
>>
>

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to