1212
1313using System . Globalization ;
1414using System . Text ;
15+ using System . Reflection ;
1516using System . Collections ;
1617using System . Windows ;
1718
1819using Microsoft . Win32 ;
1920using MS . Win32 ;
2021using MS . Internal . WindowsBase ;
21- using System . Collections . Generic ;
2222
2323namespace MS . Internal
2424{
@@ -251,42 +251,43 @@ public string Trace(TraceEventType type, int eventId, string message, string[] l
251251 {
252252 // Don't bother building the string if this trace is going to be ignored.
253253
254- if ( _traceSource == null || ! _traceSource . Switch . ShouldTrace ( type ) )
254+ if ( _traceSource == null || ! _traceSource . Switch . ShouldTrace ( type ) )
255255 return null ;
256256
257257 // Compose the trace string.
258258
259259 AvTraceBuilder traceBuilder = new AvTraceBuilder ( AntiFormat ( message ) ) ; // Holds the format string
260- List < object > combinedList = new ( parameters . Length * 2 ) ; // Holds the combined labels & parameters arrays.
261-
260+ object [ ] combinedArgs = null ; // Holds the combined labels & parameters arrays.
262261 int formatIndex = 0 ;
263262
264263 if ( ! parameters . IsEmpty && labels ? . Length > 0 )
265264 {
265+ // Create array of pre-computed size
266+ int combinedArgsLength = Math . Min ( labels . Length - 1 , parameters . Length ) * 2 ;
267+ if ( combinedArgsLength > 0 )
268+ combinedArgs = new object [ combinedArgsLength ] ;
269+
266270 int i = 1 , j = 0 ;
267271 for ( ; i < labels . Length && j < parameters . Length ; i ++ , j ++ )
268272 {
269273 // Append to the format string a "; {0} = '{1}'", where the index increments
270274 // (e.g. the second iteration will produce {2} & {3}).
271-
272275 traceBuilder . Append ( $ "; {{{formatIndex++}}}='{{{formatIndex++}}}'") ;
273276
274277 // Add the label to the combined list.
275-
276- combinedList . Add ( labels [ i ] ) ;
278+ combinedArgs [ j * 2 ] = labels [ i ] ;
277279
278280 // If the parameter is null, convert to "<null>"; otherwise,
279281 // when a string.format is ultimately called it produces bad results.
280-
281282 if ( parameters [ j ] == null )
282283 {
283- combinedList . Add ( "<null>" ) ;
284+ combinedArgs [ j * 2 + 1 ] = "<null>" ;
284285 }
285286
286287 // Otherwise, if this is an interesting object, add the hash code and type to
287288 // the format string explicitly.
288289
289- else if ( SuppressGeneratedParameters == false
290+ else if ( ! SuppressGeneratedParameters
290291 && parameters [ j ] . GetType ( ) != typeof ( string )
291292 && parameters [ j ] is not ValueType
292293 && parameters [ j ] is not Type
@@ -297,11 +298,11 @@ public string Trace(TraceEventType type, int eventId, string message, string[] l
297298
298299 // Add the parameter to the combined list.
299300
300- combinedList . Add ( parameters [ j ] ) ;
301+ combinedArgs [ j * 2 + 1 ] = parameters [ j ] ;
301302 }
302303 else // Add the parameter to the combined list.
303304 {
304- combinedList . Add ( parameters [ j ] ) ;
305+ combinedArgs [ j * 2 + 1 ] = parameters [ j ] ;
305306 }
306307 }
307308
@@ -317,12 +318,7 @@ public string Trace(TraceEventType type, int eventId, string message, string[] l
317318 // Send the trace
318319
319320 string traceMessage = traceBuilder . ToString ( ) ;
320-
321- _traceSource . TraceEvent (
322- type ,
323- eventId ,
324- traceMessage ,
325- combinedList . ToArray ( ) ) ; //Cannot avoid the alloc here, no ROS<object> overload
321+ _traceSource . TraceEvent ( type , eventId , traceMessage , combinedArgs ) ;
326322
327323 // When in the debugger, always flush the output, to guarantee that the
328324 // traces and other info (e.g. exceptions) get interleaved correctly.
0 commit comments