Skip to content

refactor: look enums up with a switch, not values() - #546

Merged
dfa1 merged 1 commit into
mainfrom
perf/enum-lookups-without-values
Oct 17, 2026
Merged

dfa1 merged 1 commit into
mainfrom
perf/enum-lookups-without-values

Conversation

@dfa1

@dfa1 dfa1 commented Oct 17, 2026

Copy link
Copy Markdown
Owner

Summary

values() allocates a fresh array on every call (64 B for PType), and the JIT does not remove it. Lookups by ordinal, tag or wire number now use a switch; places that iterate every constant take the array once.

  • PType.fromOrdinal, TimeUnit.fromTag, ZonedStatsSchema.Stat.fromOrdinal, DictLayoutDecoder, VariantEncodingDecoder: switch
  • proto-gen emits a switch for the generated ProtoPType / ProtoNullValue fromValue (was a linear scan over a fresh values()); both files regenerated, nothing else changed
  • VortexWriter and cli FileFormat: values() once into a static list
  • CLAUDE.md records the rule (Code style)

Measurements

In isolation (random ordinals, 2 forks): values()[i] 325 ops/µs and 64 B/call, switch 535 ops/µs and 0 B/call. With repeating ordinals, as in real files: values()[i] 336, switch 1,431 ops/µs. A cached array is 1,590; the switch loses to it only through jump mispredicts on random input.

No end-to-end effect: a 300-column, 16-chunk file opens and scans with the same allocation and throughput before and after (six interleaved rounds), because these lookups run a few times per column or segment. So this is a cleanup and a rule, not a speedup, and there is no CHANGELOG entry.

Test plan

  • ./mvnw verify (all modules, 2888 integration tests, javadoc)
  • round-trip tests pin each switch to its declaration order (Stat, ProtoPType, ProtoNullValue; PType and TimeUnit already had them)

🤖 Generated with Claude Code

values() allocates a fresh array on every call (64 B for PType) and the JIT does not
remove it: in isolation a values()[i] lookup is ~4x slower than a switch when the ordinals
repeat, as in real files. PType.fromOrdinal, TimeUnit.fromTag, ZonedStatsSchema.Stat,
DictLayoutDecoder and VariantEncodingDecoder now switch; proto-gen emits a switch for the
generated ProtoPType/ProtoNullValue.fromValue instead of a linear scan over values().
VortexWriter and cli FileFormat iterate all constants, so they take the array once.

No end-to-end effect: on a 300-column, 16-chunk file open and scan allocate and run the
same before and after (six interleaved rounds), because these lookups run only a few times
per column or segment. Round-trip tests pin each switch to its declaration order, and
CLAUDE.md records the rule.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@dfa1
dfa1 merged commit bb55c5f into main Oct 17, 2026
10 checks passed
@dfa1
dfa1 deleted the perf/enum-lookups-without-values branch October 18, 2026 06:18
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