forked from apache/cassandra-python-driver
-
Notifications
You must be signed in to change notification settings - Fork 49
Add __slots__ to multiple classes for memory optimization #647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
mykaul
wants to merge
7
commits into
scylladb:master
Choose a base branch
from
mykaul:slots
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+273
−243
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Add __slots__ definition to _Frame class in connection.py - Optimizes memory usage for protocol frame objects - _Frame is created for every protocol message, making this a high-impact optimization - Reduces object overhead from ~300+ bytes to ~40-60 bytes per frame - All existing functionality preserved, comprehensive tests pass Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>
d1dbc45 to
e029a81
Compare
Add __slots__ to _MessageType base class and all protocol message classes to reduce memory overhead. Each message instance saves approximately 280-300 bytes by eliminating the per-instance __dict__. Changes: - _MessageType: Added __slots__ with 'custom_payload' and 'tracing' - _MessageType: Added __init__ to initialize attributes with proper defaults - _DecodableMessageType: Removed duplicate 'custom_payload' from __slots__ - All message subclasses: Added super().__init__() calls for proper initialization Key attributes must be in __slots__ because: - custom_payload: Accessed by encode_message() for ALL message types (line 1127) - tracing: Set on message instances in cluster.py (line 2972) Without these in __slots__, attempting to set them raises AttributeError, causing connection failures with: 'OptionsMessage' object has no attribute 'custom_payload' Message classes covered: - Outgoing (_MessageType): StartupMessage, OptionsMessage, QueryMessage, ExecuteMessage, PrepareMessage, BatchMessage, RegisterMessage, etc. - Incoming (_DecodableMessageType): ResultMessage, EventMessage, AuthenticateMessage, SupportedMessage, etc. Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>
23cd816 to
c6539c5
Compare
Implemented __slots__ for ColumnMetadata and IndexMetadata classes in cassandra/metadata.py to reduce per-instance memory overhead. Changes: - ColumnMetadata: Added __slots__ with 6 attributes (table, name, cql_type, is_static, is_reversed, _cass_type) - IndexMetadata: Added __slots__ with 5 attributes (keyspace_name, table_name, name, kind, index_options) - Removed class-level attribute definitions that conflicted with __slots__ declarations - All attribute initialization moved to __init__ methods - Preserved attribute documentation in class docstrings Memory Impact: Each instance saves approximately 280-300 bytes by eliminating the per-instance __dict__. These metadata objects are created frequently when parsing schema information, making this optimization valuable for clusters with many tables and indexes. Testing: - All 648 unit tests pass successfully - Metadata-specific tests: 53 passed, 2 skipped - No functionality changes or regressions Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>
Implemented __slots__ for tablet-related classes in cassandra/tablets.py to reduce per-instance memory overhead. Changes: - Tablet class: Added __slots__ with 3 attributes (first_token, last_token, replicas) - Tablets class: Added __slots__ with 2 attributes (_tablets, _lock) - Removed class-level attribute definitions that conflicted with __slots__ - Preserved and enhanced attribute documentation in class docstrings Memory Impact: Each Tablet instance saves approximately 280-300 bytes by eliminating the per-instance __dict__. Tablet objects are created for each token range in ScyllaDB tablets-enabled clusters. In a cluster with many tablets, this optimization significantly reduces the driver's memory footprint. The Tablets class is typically a singleton per cluster, so the memory savings are minimal there, but the change maintains consistency with the optimization pattern and prevents future __dict__ usage. Testing: - All 7 tablet-specific unit tests pass - Verified __dict__ is not created (memory optimization confirmed) - No functionality changes or regressions Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>
These attributes are defined in ResponseFuture but never used: - default_timeout: Only used in Session class - _profile_manager: Only used in Session class - _warned_timeout: Never referenced anywhere Removing these attributes before adding __slots__ to ensure clean slot definitions. Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>
ResponseFuture is created for every query execution, making it a high-impact target for memory optimization. With __slots__, each instance saves approximately 900 bytes by eliminating __dict__. Memory savings at 1,000 queries/sec: ~904 KB/sec Memory savings at 10,000 queries/sec: ~9 MB/sec Changes: - Added __slots__ tuple with all 30 instance attributes - Removed class-level attribute definitions (conflicts with __slots__) - Initialize all attributes with proper defaults in __init__ - Updated test_repeat_orig_query_after_succesful_reprepare to patch at class level instead of instance level (required for __slots__) Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>
Implements __slots__ for Statement, SimpleStatement, BoundStatement, and BatchStatement classes to reduce memory overhead by eliminating per-instance __dict__. Measured memory savings (empirically verified): - Statement: 240 bytes saved (344 → 104 bytes) = 69.8% reduction - SimpleStatement: 232 bytes saved (344 → 112 bytes) = 67.4% reduction - BoundStatement: inherits full parent optimization - BatchStatement: inherits full parent optimization Classes modified: - Statement: Added __slots__ with 9 attributes (retry_policy, consistency_level, fetch_size, keyspace, table, custom_payload, is_idempotent, _serial_consistency_level, _routing_key) - SimpleStatement: Added __slots__ with 1 additional attribute (_query_string) - BoundStatement: Added __slots__ with 3 additional attributes (prepared_statement, values, raw_values) - BatchStatement: Added __slots__ with 4 additional attributes (batch_type, _statements_and_parameters, _session, _is_lwt) All 562 unit tests pass. No behavior changes. Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Add slots definition to multiple classes in the project.
It started with one set (frames), then I did additional more, each separately, in theory, independently (but they were tested only one on top of the other).
Example from frame:
Pre-review checklist
./docs/source/.Fixes:annotations to PR description.