In my experience, the more intermediate collections you eliminate, the more
you gain:
*Transducers:*
(criterium.core/with-progress-reporting
(criterium.core/quick-bench
(into []
(comp
(map inc))
(range 100000))))
Execution time mean : 3.803073 ms
Execution time std-deviation : 69.000641 µs
Execution time lower quantile : 3.715792 ms ( 2.5%)
Execution time upper quantile : 3.875992 ms (97.5%)
Overhead used : 8.938753 ns
*Good-old sequences:*
(criterium.core/with-progress-reporting
(criterium.core/quick-bench
(->> (range 100000)
(map inc)
(into []))))
Execution time mean : 5.104560 ms
Execution time std-deviation : 150.661809 µs
Execution time lower quantile : 4.904680 ms ( 2.5%)
Execution time upper quantile : 5.284278 ms (97.5%)
Overhead used : 8.938753 ns
Some improvement ~30% faster. However, with a lot of intermediary
collections:
*Transducers:*
(criterium.core/with-progress-reporting
(criterium.core/quick-bench
(into []
(comp
(map inc)
(filter odd?)
(map dec)
(filter even?)
(map (fn [n] (+ 3 n)))
(filter odd?)
(map inc)
(filter odd?)
(map dec)
(filter even?)
(map (fn [n] (+ 3 n)))
(filter odd?))
(range 100000))))
Execution time mean : 6.036796 ms
Execution time std-deviation : 95.168278 µs
Execution time lower quantile : 5.882058 ms ( 2.5%)
Execution time upper quantile : 6.125739 ms (97.5%)
Overhead used : 8.938753 ns
*Good-old sequences:*
(criterium.core/with-progress-reporting
(criterium.core/quick-bench
(->> (range 100000)
(map inc)
(filter odd?)
(map dec)
(filter even?)
(map (fn [n] (+ 3 n)))
(filter odd?)
(map inc)
(filter odd?)
(map dec)
(filter even?)
(map (fn [n] (+ 3 n)))
(filter odd?)
(into []))))
Execution time mean : 12.826507 ms
Execution time std-deviation : 345.613000 µs
Execution time lower quantile : 12.379043 ms ( 2.5%)
Execution time upper quantile : 13.193640 ms (97.5%)
Overhead used : 8.938753 ns
In this case, transducers are more than twice as fast.
On Sunday, May 8, 2016 at 3:03:23 PM UTC-7, JvJ wrote:
>
> I've been doing some code profiling lately, and I made one small change
> that drastically improved performance.
>
>
> I had this function:
>
> (defn run-systems
> "Run the systems in the order specified over
> the cross-map specified."
> ([cm] (run-systems system-order cm))
> ([order cm]
> (reduce (fn [acc f]
> (->> (get-profile f)
> (cross-cols acc)
>
> (mapcat (comp entity-pairs
> f))
>
> (into cm )))
> cm order)))
>
>
>
> Executing this function 1000 times in a row gives a runtime of about 218
> ms.
>
> By making a small change and using mapcat as a transducer:
>
> (defn run-systems
> "Run the systems in the order specified over
> the cross-map specified."
> ([cm] (run-systems system-order cm))
> ([order cm]
> (reduce (fn [acc f]
> (->> (get-profile f)
> (cross-cols acc)
> (into cm (mapcat (comp entity-pairs f)))))
> cm order)))
>
>
> The runtime goes all the way down to 169 ms.
>
> I knew that removing intermediate collections helped performance, but I
> wasn't expecting such a drastic improvement.
>
> Does anyone know similar simple tricks (either transducer-related or not
> transducer-related) that could further improve performance of these types
> of operations?
>
> (Runtime results are averaged over many runs using the criterium profiling
> library, so it's not just a fluke of thread scheduling).
>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.