Skip to content

Commit 793e074

Browse files
Improves the performance of range dramatically
Calling seq on range produced a lazy sequence which has significant overhead. Now we give Range -first and -next properties, returning start and a new Range respectively. `last` is now more efficient on IIndexed collections
1 parent 7dd29ae commit 793e074

1 file changed

Lines changed: 26 additions & 9 deletions

File tree

pixie/stdlib.pxi

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -878,9 +878,18 @@ If further arguments are passed, invokes the method named by symbol, passing the
878878
:signatures [[coll]]
879879
:added "0.1"}
880880
[coll]
881-
(if (next coll)
882-
(recur (next coll))
883-
(first coll)))
881+
(cond
882+
(satisfies? IIndexed coll)
883+
(when (pos? (count coll))
884+
(nth coll (dec (count coll))))
885+
886+
(satisfies? ISeq coll)
887+
(if (next coll)
888+
(recur (next coll))
889+
(first coll))
890+
891+
(satisfies? ISeqable coll)
892+
(recur (seq coll))))
884893

885894
(defn butlast
886895
{:doc "Returns all elements but the last from the collection."
@@ -1911,18 +1920,26 @@ For more information, see http://clojure.org/special_forms#binding-forms"}
19111920
(if (cmp val stop)
19121921
val
19131922
not-found)))
1923+
ISeq
1924+
(-first [this]
1925+
(when (not= start stop)
1926+
start))
1927+
(-next [this]
1928+
(let [i (+ step start)]
1929+
(when (or (and (> step 0) (< i stop))
1930+
(and (< step 0) (> i stop))
1931+
(and (= step 0)))
1932+
(range i stop step))))
19141933
ISeqable
1915-
(-seq [self]
1916-
(when (or (and (> step 0) (< start stop))
1917-
(and (< step 0) (> start stop)))
1918-
(cons start (lazy-seq* #(range (+ start step) stop step))))))
1934+
(-seq [self] self))
19191935

19201936
(extend -str Range
19211937
(fn [v]
1922-
(-str (seq v))))
1938+
(str "(" (transduce (interpose " ") string-builder v) ")")))
1939+
19231940
(extend -repr Range
19241941
(fn [v]
1925-
(-repr (seq v))))
1942+
(str "(" (transduce (interpose " ") string-builder v) ")")))
19261943

19271944
(defn range
19281945
{:doc "Returns a range of numbers."

0 commit comments

Comments
 (0)