Have Range implement IChunkedSeq
Description
Environment
Attachments
- 01 Jul 2018, 07:51 PM
- 23 Mar 2018, 01:19 AM
Activity
Mike Fikes November 28, 2018 at 1:32 PM
Mike Fikes November 28, 2018 at 5:11 AM
CLJS-2693.patch passes CI and Canary
Mike Fikes July 1, 2018 at 7:51 PM
The attached
CLJS-2693.patch patch depends on the patches in CLJS-2798 and CLJS-2799 having been applied.
Here are the performance speedups across the 3 major engines, covering the same metrics given in https://clojure.atlassian.net/browse/CLJ-1515#icft=CLJ-1515 (minus the ones depending on ratio support):
Code | V8 Speedup | SpiderMonkey | JavaScriptCore |
---|---|---|---|
| 5.28 | 8.58 | 7.43 |
| 4.04 | 6.41 | 2.02 |
| 5.80 | 7.53 | 2.57 |
| 4.77 | 4.39 | 1.43 |
| 1.01 | 1.00 | 1.00 |
| 1.01 | 1.00 | 1.00 |
| 1.01 | 1.00 | 0.99 |
| 0.60 | 0.98 | 0.81 |
| 0.60 | 0.94 | 0.87 |
| 0.59 | 0.88 | 0.82 |
| 1.91 | 1.58 | 1.30 |
| 0.86 | 1.00 | 1.12 |
| 0.93 | 1.04 | 1.02 |
| 1.27 | 0.97 | 0.80 |
| 1.13 | 1.02 | 0.98 |
| 1.00 | 1.15 | 0.52 |
| 1.05 | 1.06 | 0.95 |
Mike Fikes June 15, 2018 at 10:42 PM
Yes, work towards taking the spike idea and creating a production-quality change has been in progress over here https://github.com/mfikes/clojurescript/commits/CLJS-2693
David Nolen June 15, 2018 at 10:32 PM
Nice! Seems like it just needs a bit more work?
Details
Details
Assignee
Reporter
Approval
Patch
Priority

When Clojure's range was converted from a lazy seq to a
LongRange
in CLJ-1515,LongRange
was made to implementIChunkedSeq
. It seems that this could also be applicable in ClojureScript, with superficial evidence being that by taking this form(apply + (filter even? (map inc (range 1e6))))
and simply adding a call to
vec
(apply + (filter even? (map inc (vec (range 1e6)))))
dramatically speeds it up. Benchmarks are included below.
Note that Alex Miller recalls that the change in Clojure was rather challenging, with difficulty:
"balancing the perf concerns of reducible, sequence, and chunked sequence traversal (all of which are possible and may even interleave) while also avoiding potential overflow/underflow cases was a surprisingly narrow path"
Benchmarking with V8 [x (range 100000)], (apply + (filter even? (map inc x))), 10 runs, 1014 msecs Benchmarking with SpiderMonkey [x (range 100000)], (apply + (filter even? (map inc x))), 10 runs, 849 msecs Benchmarking with JavaScriptCore [x (range 100000)], (apply + (filter even? (map inc x))), 10 runs, 423 msecs Benchmarking with Nashorn [x (range 100000)], (apply + (filter even? (map inc x))), 10 runs, 2386 msecs Benchmarking with ChakraCore [x (range 100000)], (apply + (filter even? (map inc x))), 10 runs, 1798 msecs
Benchmarking with V8 [x (vec (range 100000))], (apply + (filter even? (map inc x))), 10 runs, 280 msecs Benchmarking with SpiderMonkey [x (vec (range 100000))], (apply + (filter even? (map inc x))), 10 runs, 201 msecs Benchmarking with JavaScriptCore [x (vec (range 100000))], (apply + (filter even? (map inc x))), 10 runs, 230 msecs Benchmarking with Nashorn [x (vec (range 100000))], (apply + (filter even? (map inc x))), 10 runs, 2954 msecs Benchmarking with ChakraCore [x (vec (range 100000))], (apply + (filter even? (map inc x))), 10 runs, 427 msecs