Skip to content

Cache custom attribute lookups per property descriptor - #1120

Open
lahma wants to merge 1 commit into
aaubry:masterfrom
lahma:perf/cache-custom-attributes
Open

Cache custom attribute lookups per property descriptor#1120
lahma wants to merge 1 commit into
aaubry:masterfrom
lahma:perf/cache-custom-attributes

Conversation

@lahma

@lahma lahma commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

GetCustomAttribute<T>() re-ran reflection (Attribute.GetCustomAttributes) on every call, once per property, on both the serialize and deserialize paths — profiled (ultra) at ~11% inclusive time. This memoizes the result per descriptor in a lazily-created ConcurrentDictionary, preserving the exact lookup and caching absent-attribute (null) results so the common no-attribute case is not re-reflected. Attributes are immutable metadata, so behavior is unchanged — all 1979 unit + spec tests pass; builds on net10.0/net8.0/netstandard2.0/netstandard2.1/net47.

Same-session A/B (net10.0, DefaultJob, MemoryDiagnoser):

Benchmark Baseline This PR Δ time
Alias.DeserializeWithAliases 2,358.8 µs 1,458.5 µs −38.2%
Alias.SerializeWithAliases 972.1 µs 651.5 µs −33.0%
ObjectGraph.SerializeTyped 37.55 ms 27.48 ms −26.8%
SerializationBenchmarks.Serializer 21.79 ms 17.26 ms −20.8%
ObjectGraph.DeserializeTyped 51.13 ms 41.25 ms −19.3%
ObjectGraph.RoundtripTyped 77.91 ms 65.56 ms −15.9%
ObjectGraph.DeserializeUntyped 41.99 ms 42.05 ms ~0%
YamlStream.LoadLarge (parse control) 60.50 ms 59.17 ms ~0%

Allocations unchanged (the per-descriptor dictionary is allocated once, not per operation). Benchmarks live in #1119 — merge that first to reproduce.

GetCustomAttribute<T>() re-ran reflection (Attribute.GetCustomAttributes) on every call, once per
property, on both the serialize and deserialize paths. Profiling put it at ~11% inclusive time.

Memoize the result per descriptor in a lazily-created ConcurrentDictionary, preserving the exact
lookup and caching null (absent-attribute) results so the common no-attribute case is not
re-reflected. Attributes are immutable metadata, so behavior is unchanged.
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