[perf] reduce radix cache match overhead by changing the match algorithm (#27364)
This commit is contained in:
@@ -135,37 +135,40 @@ class RadixKey:
|
||||
f"{self.extra_key=} != {other.extra_key=}"
|
||||
)
|
||||
|
||||
# TODO(Jialin): replace zip with numpy to skip per-element PyLong boxing
|
||||
def match(self, other: "RadixKey", page_size: int = 1) -> int:
|
||||
"""Logical-unit prefix length shared with ``other``. Result is rounded down to ``page_size``."""
|
||||
self._check_compatible(other)
|
||||
t0, t1 = self.token_ids, other.token_ids
|
||||
assert type(t0) is type(t1), (type(t0), type(t1))
|
||||
n = min(len(t0), len(t1))
|
||||
|
||||
# Exponential search for the first diverging token: gallop in doubling
|
||||
# windows (one C-level slice compare each), then binary-search the window
|
||||
# holding the divergence -- no per-token Python loop on long shared prefixes.
|
||||
matched_tokens = n
|
||||
lo = 0
|
||||
step = 1
|
||||
while lo < n:
|
||||
hi = lo + step if lo + step < n else n
|
||||
if t0[lo:hi] != t1[lo:hi]:
|
||||
while hi - lo > 1:
|
||||
mid = (lo + hi) // 2
|
||||
if t0[lo:mid] == t1[lo:mid]:
|
||||
lo = mid
|
||||
else:
|
||||
hi = mid
|
||||
matched_tokens = lo
|
||||
break
|
||||
lo = hi
|
||||
step *= 2
|
||||
|
||||
if self.is_bigram:
|
||||
# Walk raw tokens; L matching tokens imply L-1 matching bigrams.
|
||||
i = 0
|
||||
for a, b in zip(t0, t1):
|
||||
if a != b:
|
||||
break
|
||||
i += 1
|
||||
matched = max(0, min(i - 1, len(self), len(other)))
|
||||
matched = max(0, min(matched_tokens - 1, len(self), len(other)))
|
||||
return (matched // page_size) * page_size if page_size > 1 else matched
|
||||
|
||||
if page_size == 1:
|
||||
i = 0
|
||||
for a, b in zip(t0, t1):
|
||||
if a != b:
|
||||
break
|
||||
i += 1
|
||||
return i
|
||||
|
||||
min_len = min(len(self), len(other))
|
||||
i = 0
|
||||
while i < min_len:
|
||||
if t0[i : i + page_size] != t1[i : i + page_size]:
|
||||
break
|
||||
i += page_size
|
||||
return i
|
||||
return matched_tokens
|
||||
return (matched_tokens // page_size) * page_size
|
||||
|
||||
def child_key(self, page_size: int = 1):
|
||||
"""Hashable dict-key for the first ``page_size`` logical units, namespaced by ``extra_key``."""
|
||||
|
||||
Reference in New Issue
Block a user