Skip to content

Commit 2155561

Browse files
committed
[WIP] Optimization: Improve performance for repetitive lookup
CacheLookupTable leaves the bucket vacant when the object is freed. Because of this, in the worst case, subscript have to perform full linear search for all buckets. Let's say we have a table like this: bucket 0: obj1(hash: 0) bucket 1: obj2(hash: 1) bucket 2: nil bucket 3: obj3(hash: 0) bucket 4: nil If obj1 is freed, it become: bucket 0: nil bucket 1: obj2(hash: 1) bucket 2: nil bucket 3: obj3(hash: 0) bucket 4: nil When looking-up obj3, the search starts from "bucket 0", thus it needs 3 iteration. This patch moves the obj3 to "bucket 0" the first nil hole found. So the next lookup doesn't need any iteration. bucket 0: obj3(hash: 0) bucket 1: obj2(hash: 1) bucket 2: nil bucket 3: nil bucket 4: nil
1 parent 022c47f commit 2155561

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

Sources/SwiftSyntax/CacheLookupTable.swift

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,25 @@ class CacheLookupTable<T: Identifiable & AnyObject> {
201201
// we expect it's stored near the 'idealBucket' anyway.
202202
let idealBucket = _idealBucket(for: id)
203203
var bucket = idealBucket
204+
var firstHole: Int? = nil
204205
repeat {
205-
if buckets[bucket].value?.id == id {
206-
return buckets[bucket].value
206+
if let obj = buckets[bucket].value {
207+
if obj.id == id {
208+
if let firstHole = firstHole {
209+
// Move the object to the first hole found. This improves lookup
210+
// performance in the next lookup.
211+
let holeP = buckets + firstHole
212+
let bucketP = buckets + bucket
213+
214+
let tmp = holeP.move()
215+
holeP.moveInitialize(from: bucketP, count: 1)
216+
bucketP.initialize(to: tmp)
217+
}
218+
return obj
219+
}
220+
} else if firstHole == nil {
221+
// Remember the first hole found.
222+
firstHole = bucket
207223
}
208224
bucket = (bucket &+ 1) & _bucketMask
209225
} while bucket != idealBucket

0 commit comments

Comments
 (0)