You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While investigating Sprocket's baseline memory usage, certain
workloads—particularly those involving deeply nested compound types like
`Map[String, Map[String, ...]]`—scaled poorly. The root cause was the
`Value` enum in `wdl-engine`, which occupied 96 bytes per element due to
large inline types (`Type` at 56 bytes, `TaskPostEvaluationValue` at 96
bytes) inflating the enum even though the common case (`PrimitiveValue`)
is only 16 bytes.
This refactor pushes `Arc` wrapping down into the types that inflate
`Value`. Each compound value type (`Array`, `Map`, `Pair`, `Struct`,
`EnumVariant`) and each large hidden value type (`TaskPreEvaluation`,
`TaskPostEvaluation`) becomes a thin wrapper around `Arc<Inner>`, where
the inner struct owns all fields directly—eliminating nested `Arc`
layering. Two new wrapper types (`NoneValue` and `TypeNameRefValue`)
handle variants that previously stored a bare `Type`. `CallValue` wraps
its `CallType` field behind `Arc` as well.
The tradeoff is an additional pointer indirection when accessing fields
of compound and hidden values, since their data now lives behind `Arc`
on the heap rather than inline in the enum. In practice, this cost is
negligible: these types were already heap-allocated internally (e.g.,
`Array` stored an `Arc<Vec<Value>>`), so the refactor consolidates
rather than adds indirection. Clone remains cheap—a refcount bump on
one `Arc` rather than multiple.
A const assertion prevents `Value` from exceeding 24 bytes in the
future. The `as_map` standard library function was also updated to use
the `IndexMap` entry API, eliminating a redundant key clone.
See PR for benchmark results.
Relates to #541.
0 commit comments