microsoft / perfview

PerfView is a CPU and memory performance-analysis tool
http://channel9.msdn.com/Series/PerfView-Tutorial
MIT License
4.2k stars 712 forks source link

Initializing StructValues with list size to save allocations #2106

Closed clutterloh closed 3 months ago

clutterloh commented 3 months ago

We use TraceEvent to gather process-level event counters. I noticed in a recent trace that about 12% of our process memory allocations are due to resizing when we call DynamicTraceEventData.PayloadValue(int32)

In particular, the system.private.corelib.il!System.Collections.Generic.List`1[System.Collections.Generic.KeyValuePair`2[System.__Canon, System.__Canon]].AddWithResize(System.__Canon) and system.private.corelib.il!System.Collections.Generic.List`1[System.Collections.Generic.KeyValuePair`2[System.__Canon, System.__Canon]].set_Capacity(int32) frames caused by list resizing.

I noticed in the code that when GetPayloadValueAt(...) is called a StructValue is created and we go through a loop adding i KeyValuePairs corresponding to classInfo.FieldFetches.Length. https://github.com/microsoft/perfview/blob/4685da655131acb73441f71ec19ea79ffa300ffa/src/TraceEvent/DynamicTraceEventParser.cs#L606C17-L612C18

Is there anything preventing us from adding a constructor to StructValue that lets us specify an initial size and avoid all the reallocations when resizing the internal m_values list?

clutterloh commented 3 months ago

https://github.com/microsoft/perfview/pull/2107