experiment(value): evaluate flat ObjectMap backends#1826
Draft
lukesteensen wants to merge 8 commits into
Draft
Conversation
Many call sites were creating a String allocation only to immediately convert it to KeyString. This is wasteful because KeyString::from(&str) and KeyString::from(Cow<str>) can construct directly without the intermediate heap allocation. The most impactful fix is in crud/insert.rs where field.to_string().into() was called on every VRL path insertion — field is Cow<str> (usually Borrowed), so this was allocating on every event for no reason. Also fixes ~20 other sites across stdlib parsers (parse_syslog, parse_grok, parse_key_value, flatten, unflatten, tally, etc.) and the value! macro where literal strings went through String::from() first. These changes are independently valuable with String-backed KeyString (saves one allocation per conversion) and become even more important with SSO string types where the &str path can inline short strings with zero allocation.
Four benchmark groups for comparing KeyString backing types: - keystring_micro: construction, clone, roundtrip costs - path_ops: owned vs JIT path traversal - vrl_programs: end-to-end VRL execution (remap, parse_syslog, flatten, object construction) - json_deser: serde_json::Value intermediate vs direct deserialization
Rename from_long_str/clone_long to from_medium_str/clone_medium (22B, within CompactString inline but spills EcoString). Add true from_long_str/clone_long at 31B that spills both SSO types for a fair heap-allocated comparison.
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
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.
Summary
This is an experimental PR evaluating alternative
ObjectMapstorage layouts.The goal is to improve memory locality and clone/allocation efficiency for VRL
object values. Today
ObjectMapis effectively BTree-backed, which gives goodlookup behavior but poor locality and expensive structural clones. This branch
adds enum-backed
ObjectMapvariants so we can compare the current BTree layoutagainst flatter vector-backed layouts.
The enum is mostly experimental scaffolding. It lets us compare designs, but it
also adds cost through larger object size and extra branching. If we identify a
winning representation, implementing that representation directly should be
better than keeping enum dispatch in the hot path.
What changed
ObjectMapstorage variants.ObjectMapexperiments.ObjectMapis aBTreeMap.ObjectMapbenchmarks:objectmapobjectmap_cliffobjectmap_hybridKeyStringconstruction cleanup and benchmarks.Benchmark takeaways
The isolated benchmarks show the expected tradeoff:
However, the more realistic cloned-event benchmarks are much more promising:
objectmap_cliff/realistic_eventfavors flat maps from roughly width 16 onward.objectmap_cliff/realistic_event_readonlystrongly favors flat maps becauseclones remain cheap and no mutation forces extra work.
So the experiment suggests the core hypothesis is valid: improving memory
locality and clone efficiency can outweigh worse isolated lookup behavior in
realistic VRL/event workloads.
KeyString changes
This branch also includes independent
KeyStringcleanup.Several call sites were constructing temporary
Strings only to immediatelyconvert them into
KeyString. With today’sString-backedKeyString, theimpact is small because LLVM can often optimize the extra work away. The cleanup
becomes more important if we later move
KeyStringto an SSO/refcounted backingtype, where direct construction from
&str/Cow<str>can avoid heap allocation.These changes are separable from the
ObjectMapexperiment, but came out of thesame performance investigation.
API compatibility
This is technically a breaking change.
ObjectMap/Value::Objecthave exposedBTreeMap-specific behavior andconstruction patterns publicly. External code that constructs, destructures, or
uses
Value::Objectas aBTreeMapwill need to move toObjectMapAPIsinstead.
This is part of the experiment: hiding the backing map type is necessary if we
want freedom to change the representation.
Validation
Local checks run:
Open questions
such that we would have confidence turning it on by default?
despite its cost, or should we switch to a single winning representation once
the design is chosen?