Skip to content

[CASSANDRA-21587] Megamorphic call in ClusteringPrefix.Deserializer.deserializeOne slows down readseserializeOne slows down reads - #5039

Open
koo-taejin wants to merge 1 commit into
apache:trunkfrom
koo-taejin:CASSANDRA-21587-trunk
Open

[CASSANDRA-21587] Megamorphic call in ClusteringPrefix.Deserializer.deserializeOne slows down readseserializeOne slows down reads#5039
koo-taejin wants to merge 1 commit into
apache:trunkfrom
koo-taejin:CASSANDRA-21587-trunk

Conversation

@koo-taejin

Copy link
Copy Markdown
Contributor

Description

ClusteringPrefix.Deserializer.deserializeOne() reads clustering components in a hot partition-scan loop:

  serializationHeader.clusteringTypes()
                     .get(i)
                     .readArray(in, DatabaseDescriptor.getMaxValueSize());

clusteringTypes() is declared as List, but its runtime implementation differs by header source:

  • SSTable Stats component read from disk: ArrayList
  • Flush or compaction with one clustering column: SingletonImmutableList
  • Flush or compaction with multiple clustering columns: RegularImmutableList

This makes the List.get() call megamorphic. HotSpot can optimize one or two receiver types, but the third ArrayList receiver forces a slower interface-table dispatch.

Fix

Change AbstractTypeSerializer.deserializeList() to return an ImmutableList built with ImmutableList.builderWithExpectedSize(size).

This removes the SSTable-only ArrayList receiver. The call site remains bimorphic:

  • One clustering column: SingletonImmutableList
  • Multiple clustering columns: RegularImmutableList

Numbers

Production node, async-profiler, 120 seconds, 97,036 CPU samples:

  • deserializeOne inclusive: 4,869 samples, 5.0% of total CPU
  • Interface-table stub from clusteringTypes().get(i): 608 samples, 0.63% of total CPU
  • Approximately one eighth of deserializeOne CPU time is dispatch overhead rather than deserialization work.

JMH benchmark with controlled receiver count:

  • 3 receiver classes: 1129.1 ± 17.1 ns/op
  • 2 receiver classes: 981.4 ± 34.8 ns/op
  • 1 receiver class: 934.7 ± 27.4 ns/op

patch by koo.taejin; reviewed by for CASSANDRA-21587

The Cassandra Jira

…eserializeOne slows down reads

Avoid a third List implementation in ClusteringPrefix.Deserializer's hot path by deserializing clustering types into ImmutableList. Add regression coverage and a JMH benchmark for the memtable and SSTable header paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant