Skip to content

Commit 8a8fcd3

Browse files
marcobiscaro2112puredanger
authored andcommitted
TCHECK-160 Reduce shrink-int allocation churn
`shrink-int` has LazySeq allocation churn that can be avoided by special casing long values. This can have a significant impact (in allocations and in run time) because `shrink-int` is used as foundation for `choose`, which in turn is used by many generators. For example, the following snippet: (core/let [g (vector (not-empty string-alphanumeric) 1000 5000)] (time (dotimes [seed 50] (dorun (generate g 100 seed))))) runs ~26% faster (from 22541ms to 16741ms) and allocates ~16% less (from 15.05GB to 12.66GB) after this patch. Measured on jdk 25 with `-Xmx512m -XX:+UseSerialGC`.
1 parent 32957f2 commit 8a8fcd3

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

src/main/clojure/clojure/test/check/generators.cljc

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,40 @@
202202
;; Internal Helpers
203203
;; ---------------------------------------------------------------------------
204204

205+
#?(:clj
206+
(defn- shrink-long
207+
[^long x]
208+
; Returns a long array (instead of a lazy seq) to avoid allocation churn.
209+
; The size of returned array is log2(abs(x)), computed from the number
210+
; of significant bits.
211+
(core/let [size (- 64 (Long/numberOfLeadingZeros (Math/abs x)))
212+
^longs vals (long-array size)]
213+
(loop [i 0 n x]
214+
(if (zero? n)
215+
vals
216+
(do
217+
(aset vals i (- x n))
218+
(recur (inc i) (quot n 2))))))))
219+
205220
(defn- halfs
206221
[n]
207222
(take-while #(not= 0 %) (iterate #(quot % 2) n)))
208223

209-
(defn- shrink-int
224+
(defn- shrink-big-int
210225
[integer]
211226
(core/map #(- integer %) (halfs integer)))
212227

228+
(defn- shrink-int
229+
"Given a number x, returns a coll of (x-x, x-x/2, x-x/4, x-x/8, ..., x-1)"
230+
[x]
231+
#?(:clj
232+
(if (<= Long/MIN_VALUE x Long/MAX_VALUE)
233+
(shrink-long x)
234+
(shrink-big-int x))
235+
236+
:cljs
237+
(shrink-big-int x)))
238+
213239
(defn- int-rose-tree
214240
[value]
215241
(rose/make-rose value (core/map int-rose-tree (shrink-int value))))

0 commit comments

Comments
 (0)