Optimized long range not used for int args

Description

range has a highly optimized implementation (LongRange) for the very common case where all range arguments are longs. However, a common case is: (range (count x)) for some coll x. count returns an int, and thus the optimized range is not used, even though it could be.

A workaround right now is to explicitly coerce:

(range (long (count x)))

Approach

Widen check of arguments to range to see if they are fixed-precision integers per int? (covers: long, int, short, byte in that order), instead of explicit check of instanceof java.lang.Long, increasing the cases where . The LongRange.create() methods take longs so the JVM will upcast to long primitives.

Perf

Timings

Version

(last (range 10000))

(last (range (count coll)))

1.11.1

300 ms

413 ms

1.12.0-alpha1

113 ms

386 ms

1.12.0-master on 1/30/2023

108 ms

433 ms

1.12.0-master on 1/30/2023 + patch

110 ms

110 ms (78% better)

(now using LongRange)

I included several versions here as we’ve been changing things in this area so it really matters what you’re comparing against - 1.12.0-alpha1 has lots of range improvements. The changes from alpha1 to master should not have any effect on this test so not sure why seeing 386-433 ms there, may just be sampling error. But importantly, with this patch, LongRange is used which is the optimized path.

Patch: clj-2709-1.patch

Screened by: Alex Miller

Environment

None

Attachments

1

Activity

Show:

Alex MillerMarch 8, 2023 at 3:52 PM

Applied for release in 1.12.0-alpha2

Fixed

Details

Assignee

Reporter

Approval

Ok

Patch

Code

Priority

Affects versions

Fix versions

Created May 10, 2022 at 3:33 PM
Updated March 8, 2023 at 3:52 PM
Resolved March 8, 2023 at 3:52 PM