1111
1212using System . Globalization ;
1313using System . Text ;
14+ using System . Reflection ;
1415using System . Collections ;
1516using System . Windows ;
1617
1718using Microsoft . Win32 ;
1819using MS . Win32 ;
1920using MS . Internal . WindowsBase ;
20- using System . Collections . Generic ;
2121
2222namespace MS . Internal
2323{
@@ -250,42 +250,43 @@ public string Trace(TraceEventType type, int eventId, string message, string[] l
250250 {
251251 // Don't bother building the string if this trace is going to be ignored.
252252
253- if ( _traceSource == null || ! _traceSource . Switch . ShouldTrace ( type ) )
253+ if ( _traceSource == null || ! _traceSource . Switch . ShouldTrace ( type ) )
254254 return null ;
255255
256256 // Compose the trace string.
257257
258258 AvTraceBuilder traceBuilder = new AvTraceBuilder ( AntiFormat ( message ) ) ; // Holds the format string
259- List < object > combinedList = new ( parameters . Length * 2 ) ; // Holds the combined labels & parameters arrays.
260-
259+ object [ ] combinedArgs = null ; // Holds the combined labels & parameters arrays.
261260 int formatIndex = 0 ;
262261
263262 if ( ! parameters . IsEmpty && labels ? . Length > 0 )
264263 {
264+ // Create array of pre-computed size
265+ int combinedArgsLength = Math . Min ( labels . Length - 1 , parameters . Length ) * 2 ;
266+ if ( combinedArgsLength > 0 )
267+ combinedArgs = new object [ combinedArgsLength ] ;
268+
265269 int i = 1 , j = 0 ;
266270 for ( ; i < labels . Length && j < parameters . Length ; i ++ , j ++ )
267271 {
268272 // Append to the format string a "; {0} = '{1}'", where the index increments
269273 // (e.g. the second iteration will produce {2} & {3}).
270-
271274 traceBuilder . Append ( $ "; {{{formatIndex++}}}='{{{formatIndex++}}}'") ;
272275
273276 // Add the label to the combined list.
274-
275- combinedList . Add ( labels [ i ] ) ;
277+ combinedArgs [ j * 2 ] = labels [ i ] ;
276278
277279 // If the parameter is null, convert to "<null>"; otherwise,
278280 // when a string.format is ultimately called it produces bad results.
279-
280281 if ( parameters [ j ] == null )
281282 {
282- combinedList . Add ( "<null>" ) ;
283+ combinedArgs [ j * 2 + 1 ] = "<null>" ;
283284 }
284285
285286 // Otherwise, if this is an interesting object, add the hash code and type to
286287 // the format string explicitly.
287288
288- else if ( SuppressGeneratedParameters == false
289+ else if ( ! SuppressGeneratedParameters
289290 && parameters [ j ] . GetType ( ) != typeof ( string )
290291 && parameters [ j ] is not ValueType
291292 && parameters [ j ] is not Type
@@ -296,11 +297,11 @@ public string Trace(TraceEventType type, int eventId, string message, string[] l
296297
297298 // Add the parameter to the combined list.
298299
299- combinedList . Add ( parameters [ j ] ) ;
300+ combinedArgs [ j * 2 + 1 ] = parameters [ j ] ;
300301 }
301302 else // Add the parameter to the combined list.
302303 {
303- combinedList . Add ( parameters [ j ] ) ;
304+ combinedArgs [ j * 2 + 1 ] = parameters [ j ] ;
304305 }
305306 }
306307
@@ -316,12 +317,7 @@ public string Trace(TraceEventType type, int eventId, string message, string[] l
316317 // Send the trace
317318
318319 string traceMessage = traceBuilder . ToString ( ) ;
319-
320- _traceSource . TraceEvent (
321- type ,
322- eventId ,
323- traceMessage ,
324- combinedList . ToArray ( ) ) ; //Cannot avoid the alloc here, no ROS<object> overload
320+ _traceSource . TraceEvent ( type , eventId , traceMessage , combinedArgs ) ;
325321
326322 // When in the debugger, always flush the output, to guarantee that the
327323 // traces and other info (e.g. exceptions) get interleaved correctly.
0 commit comments