[perf] reduce radix cache match overhead by changing the match algorithm (#27364)

This commit is contained in:
Qiaolin Yu
2026-06-06 15:40:28 -07:00
committed by GitHub
parent 1c7acba579
commit 4b0f629082
2 changed files with 79 additions and 22 deletions
@@ -142,6 +142,60 @@ class TestRadixKey(unittest.TestCase):
repr_str = repr(key)
self.assertIn("...", repr_str) # Should be truncated
def _assert_match(self, a, b, page_size, expected, is_bigram=False):
key_a = RadixKey(array("q", a), is_bigram=is_bigram)
key_b = RadixKey(array("q", b), is_bigram=is_bigram)
self.assertEqual(key_a.match(key_b, page_size=page_size), expected)
def test_match_page_size_1(self):
"""match() with page_size=1: full, partial, none, prefix, and empty keys."""
self._assert_match([1, 2, 3, 4], [1, 2, 3, 4], 1, 4) # identical
self._assert_match([1, 2, 3, 4], [1, 2, 9, 9], 1, 2) # diverge at index 2
self._assert_match([9, 2, 3], [1, 2, 3], 1, 0) # diverge at index 0
self._assert_match([1, 2, 3, 4], [1, 2, 3], 1, 3) # other is a prefix
self._assert_match([], [1, 2], 1, 0) # empty self
self._assert_match([1, 2], [], 1, 0) # empty other
self._assert_match([], [], 1, 0) # both empty
def test_match_page_size_gt_1_rounds_down(self):
"""match() with page_size>1 rounds the shared length down to a page."""
self._assert_match([1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 9, 8], 4, 4)
self._assert_match(
[1, 2, 3, 4], [1, 9, 3, 4], 4, 0
) # diverge inside first page
self._assert_match([1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 9, 6, 7, 8], 4, 4)
self._assert_match([1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7, 8], 4, 8)
self._assert_match([1, 2, 3], [1, 2, 3], 4, 0) # shorter than one page
def test_match_long_keys_exponential_search(self):
"""Deep divergences exercise the doubling gallop windows + binary search.
``base`` has distinct values, so flipping one position diverges the prefix
exactly there; the shared length is that index rounded down to the page.
"""
base = list(range(2000))
for div in (1, 2, 63, 64, 65, 127, 128, 511, 512, 513, 1234, 1999):
b = base[:]
b[div] = -1
for page_size in (1, 4, 64):
with self.subTest(div=div, page_size=page_size):
self._assert_match(
base, b, page_size, (div // page_size) * page_size
)
# Full match of a long key: the gallop must reach the end.
self._assert_match(base, base[:], 64, (2000 // 64) * 64)
def test_match_bigram(self):
"""is_bigram: L matching raw tokens imply L-1 matching bigrams."""
self._assert_match([1, 2, 3, 4, 5], [1, 2, 3, 9, 5], 1, 2, is_bigram=True)
self._assert_match([1, 2, 3, 4, 5], [1, 2, 3, 4, 5], 1, 4, is_bigram=True)
self._assert_match([1, 2], [1, 2], 1, 1, is_bigram=True)
# Raw diverge at token 70 -> 69 matching bigrams -> rounded down to 64.
long_a = list(range(130))
long_b = list(range(130))
long_b[70] = -1
self._assert_match(long_a, long_b, 64, 64, is_bigram=True)
class TestTreeNode(unittest.TestCase):
"""Test cases for TreeNode class."""