[
https://issues.apache.org/jira/browse/CASSANDRA-20167?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17912258#comment-17912258
]
Dmitry Konstantinov commented on CASSANDRA-20167:
-------------------------------------------------
Hi, I have decomposed the whole change set to the following logical parts:
||N||Change scope|| Alloc benefit as % of the full change set||API
changes||MR/patch||Suggestion||
|1|Avoid unnecessary iterators for the write hot path, do not recreate
immutable objects with the same content, avoid objects allocations used only in
rarely invoked logic branches, memorize things which can be computed
once|60%|single primitive one: to add an override method
VIewManager.updatesAffectView with a single element to avoid collection
creation to invoke it|TBD|to merge to 5.0 in this ticket|
|2|Reduce memory allocation in CQL transport logic:
* Parse header and query options flags as int, without EnumSet overheads
* avoid ByteBuffer slicing in 2 places
* avoid a capturing lambda allocation by using an explicit interface|5.5%| *
expose Header flags as int instead of EnumSet - it impacts only 2 classes
within the same package
* add an explicit functional interface for OnFlushCleanup instead of
Consumer<FlushItem<Envelope>>|TBD|to merge to 5.0 in this ticket if possible or
to extract to a separate ticket to evaluate separately|
|3|Reduce memory allocation Mutation/PartitionUpdate logic:
* avoid an unnecessary byte buffer slicing (DataOutputBuffer.toByteArray())
during a Mutation serialization
* Replace AtomicLong viewLockAcquireStart field in Mutation with volatile
long and AtomicLongFieldUpdater usage|5%|Add new method to
DataOutputBuffer.unsafeToByteArray() (similar to a recently added
unsafeGetBufferAndFlip())|TBD|to merge to 5.0 in this ticket if possible or to
extract to a separate ticket to evaluate separately|
|4|Use simplified iterator logic for PartitionUpdate to avoid
LeafBTreeSearchIterator within inclusionTester()|7.6%|Add new builder method in
ColumnFilter: all(RegularAndStaticColumns columns)|TBD|to merge to 5.0 in this
ticket if possible or to extract to a separate ticket to evaluate separately|
|5|Cache BtreeRow.builder in a thread-local tiny pool to reuse in
UpdateParameters|4.6%|BTreeRow.pooledUnsortedBuilder method is added|TBD|to
merge to 5.0 in this ticket if possible or to extract to a separate ticket to
evaluate separately|
|6|Add optimized version of UpdatesCollector for a single partition update
within a single table (a very typical case when we just modify a row)|10%|no
existing API changes
We introduce a new implementation for UpdatesCollector, theoretically we have
now 3 implementations of UpdatesCollector interface and
addUpdates() call can be megamorphic but it is not an issue, because:
1) multi-table batch is no a frequent case (so, in majority of cases the call
will be bimorphic)
2) addUpdates is big enough by itself and invoked once per partition, so the
overheads of a megamorphic call for this callsite (even if we have it) are are
limited
3) benefits to not create and fill HashMultiset + 2 HashMap instances are much
higher |TBD|to merge to 5.0 in this ticket if possible or to extract to a
separate ticket to evaluate separately|
|7|Optimize a typical case: a single clustering key in an update|3%|Add new
method to MultiCBuilder.buildSingle()|TBD|Can be moved to 5.1 if needed|
|8|Avoid ImmutableList.copyOf(columnSpecs) within
OptionsWithColumnSpecifications constructor, we have to copy columnSpecs for
every request because in one place plain List is used and in another -
ImmutableList|2.3%|Change collection type from List to ImmutableList for a set
of methods in CQLStatement/QueryOptionsAdd a new method to
VariableSpecifications.|TBD|Move to 5.1|
|9|iterate over restriction set as an array to avoid iterator usage|0.1%|Add
RestrictionSet.toArray() method|TBD|Move to 5.1 or drop due to a too small win|
note: I rounded % so the sum is slightly less than 100%
So, the suggestion:
# To merge to 5.0 in the context of the current story, options:
## minimal (1) row from the table; 60% of benefits, basic changes
## medium: (1) + (4) + (6); 77.6% of benefits
## bigger: (1) + (2) + (3) + (4) + (5) + (6) + (7)?; 95.7% of benefits
# (9) change I suggest to just drop due to a too small win by itself for the
amount of changes
# (8) or (7) + (8) - move to 5.1
# if something from (2) + (3) + (4) + (5) + (6) + (7) is too big in
combination with others for this story - we can evaluate them more precisely
part by part in separate stories (each change by itself is quite simple and
straightforward).
> Reduce memory allocations in miscellaneous places along write path
> ------------------------------------------------------------------
>
> Key: CASSANDRA-20167
> URL: https://issues.apache.org/jira/browse/CASSANDRA-20167
> Project: Apache Cassandra
> Issue Type: Improvement
> Components: Consistency/Coordination, Local/Other
> Reporter: Dmitry Konstantinov
> Assignee: Dmitry Konstantinov
> Priority: Normal
> Fix For: 5.0.x
>
> Attachments: ci_summary_netudima_20167-5.0_147.html,
> image-2024-12-26-22-01-32-592.png, image-2024-12-26-22-01-55-614.png,
> image-2024-12-26-22-02-44-040.png, image-2024-12-26-22-03-49-018.png,
> results_details_netudima_20167-5.0_147.tar.xz
>
> Time Spent: 2h 10m
> Remaining Estimate: 0h
>
> Avoid unnecessary allocations in different places along write path:
> * avoid iterator allocations if possible
> * handle typical cases (such as a single row, single table writes) more
> efficiently
> * add fast paths for typical scenarios (like pending ranges is empty)
> * memorize things which can be computed once
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]