From 57c84ff129de4ab8072bbc9756942650803001ef Mon Sep 17 00:00:00 2001 From: cong-or Date: Fri, 6 Mar 2026 06:04:09 +0000 Subject: [PATCH] perf: add __slots__ to KVCacheBlock (#36164) Signed-off-by: cong-or --- tests/v1/core/test_kv_cache_utils.py | 12 ++++++++++++ vllm/v1/core/kv_cache_utils.py | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/v1/core/test_kv_cache_utils.py b/tests/v1/core/test_kv_cache_utils.py index 2c4dab3f8..08463a280 100644 --- a/tests/v1/core/test_kv_cache_utils.py +++ b/tests/v1/core/test_kv_cache_utils.py @@ -202,6 +202,18 @@ def test_kv_cache_block(): assert block.block_hash is None +def test_kv_cache_block_uses_slots(): + block = KVCacheBlock(block_id=0) + + # Slots eliminate per-instance __dict__, saving ~264 bytes per block. + # At 100K+ blocks this avoids tens of MB of overhead and GC pressure. + assert not hasattr(block, "__dict__") + + # Verify that slots actually prevent dynamic attribute assignment. + with pytest.raises(AttributeError): + block.unexpected_field = True + + def test_free_kv_cache_block_queue_initialization(): # Test with a single block block = KVCacheBlock(block_id=0) diff --git a/vllm/v1/core/kv_cache_utils.py b/vllm/v1/core/kv_cache_utils.py index cfaa37074..2ed7ef7e0 100644 --- a/vllm/v1/core/kv_cache_utils.py +++ b/vllm/v1/core/kv_cache_utils.py @@ -106,7 +106,7 @@ def init_none_hash(hash_fn: Callable[[Any], bytes]): NONE_HASH = BlockHash(hash_fn(hash_seed)) -@dataclass +@dataclass(slots=True) class KVCacheBlock: """KV-cache block metadata."""