Skip to content

Commit c700781

Browse files
oscardssmithmbaumanvtjnash
authored
Use faster hash for short arrays. (#39966)
* Use faster hash for AbstractArrays. Since the current code already hashes all elements of small arrays (<4096 elements), this is basically a fast-path that avoids a lot of the math. It also xors the hashes, which should allow the compiler to vectorize hashing. As a result, I'm measuring about a 4x speedup for hashing a 20x20 matrix, and have not found cases where this is slower. In addition, we can only hash the values for all arrays yielding to a 2x speedup. Co-authored-by: Matt Bauman <[email protected]> Co-authored-by: Jameson Nash <[email protected]>
1 parent dca0850 commit c700781

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

base/abstractarray.jl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,7 +2403,14 @@ function hash(A::AbstractArray, h::UInt)
24032403
# Instead hash the tuple of firsts and lasts along each dimension
24042404
h = hash(map(first, axes(A)), h)
24052405
h = hash(map(last, axes(A)), h)
2406-
isempty(A) && return h
2406+
2407+
# For short arrays, it's not worth doing anything complicated
2408+
if length(A) < 8192
2409+
for x in A
2410+
h = hash(x, h)
2411+
end
2412+
return h
2413+
end
24072414

24082415
# Goal: Hash approximately log(N) entries with a higher density of hashed elements
24092416
# weighted towards the end and special consideration for repeated values. Colliding
@@ -2434,9 +2441,8 @@ function hash(A::AbstractArray, h::UInt)
24342441
n = 0
24352442
while true
24362443
n += 1
2437-
# Hash the current key-index and its element
2438-
elt = A[keyidx]
2439-
h = hash(keyidx=>elt, h)
2444+
# Hash the element
2445+
h = hash(A[keyidx], h)
24402446

24412447
# Skip backwards a Fibonacci number of indices -- this is a linear index operation
24422448
linidx = key_to_linear[keyidx]

0 commit comments

Comments
 (0)