@@ -272,6 +272,35 @@ internal static partial class Number
272
272
273
273
// Optimizations using "TwoDigits" inspired by:
274
274
// https://engineering.fb.com/2013/03/15/developer-tools/three-optimization-tips-for-c/
275
+ #if MONO
276
+ // Workaround for a performance regression on Mono: https://github.com/dotnet/runtime/issues/111932
277
+ private static readonly byte [ ] TwoDigitsCharsAsBytes =
278
+ MemoryMarshal . AsBytes < char > ( "00010203040506070809" +
279
+ "10111213141516171819" +
280
+ "20212223242526272829" +
281
+ "30313233343536373839" +
282
+ "40414243444546474849" +
283
+ "50515253545556575859" +
284
+ "60616263646566676869" +
285
+ "70717273747576777879" +
286
+ "80818283848586878889" +
287
+ "90919293949596979899" ) . ToArray ( ) ;
288
+ private static readonly byte [ ] TwoDigitsBytes =
289
+ ( "00010203040506070809"u8 +
290
+ "10111213141516171819"u8 +
291
+ "20212223242526272829"u8 +
292
+ "30313233343536373839"u8 +
293
+ "40414243444546474849"u8 +
294
+ "50515253545556575859"u8 +
295
+ "60616263646566676869"u8 +
296
+ "70717273747576777879"u8 +
297
+ "80818283848586878889"u8 +
298
+ "90919293949596979899"u8 ) . ToArray ( ) ;
299
+
300
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
301
+ private static ref byte GetTwoDigitsBytesRef ( bool useChars ) =>
302
+ ref MemoryMarshal . GetArrayDataReference ( useChars ? TwoDigitsCharsAsBytes : TwoDigitsBytes ) ;
303
+ #else
275
304
private static ReadOnlySpan < byte > TwoDigitsCharsAsBytes =>
276
305
MemoryMarshal . AsBytes < char > ( "00010203040506070809" +
277
306
"10111213141516171819" +
@@ -295,6 +324,12 @@ internal static partial class Number
295
324
"80818283848586878889"u8 +
296
325
"90919293949596979899"u8 ;
297
326
327
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
328
+ private static ref byte GetTwoDigitsBytesRef ( bool useChars ) =>
329
+ ref MemoryMarshal . GetReference ( useChars ? TwoDigitsCharsAsBytes : TwoDigitsBytes ) ;
330
+ #endif
331
+
332
+
298
333
public static unsafe string FormatDecimal ( decimal value , ReadOnlySpan < char > format , NumberFormatInfo info )
299
334
{
300
335
char fmt = ParseFormatSpecifier ( format , out int digits ) ;
@@ -1572,7 +1607,7 @@ internal static unsafe void WriteTwoDigits<TChar>(uint value, TChar* ptr) where
1572
1607
1573
1608
Unsafe . CopyBlockUnaligned (
1574
1609
ref * ( byte * ) ptr ,
1575
- ref Unsafe . Add ( ref MemoryMarshal . GetReference ( typeof ( TChar ) == typeof ( char ) ? TwoDigitsCharsAsBytes : TwoDigitsBytes ) , ( uint ) sizeof ( TChar ) * 2 * value ) ,
1610
+ ref Unsafe . Add ( ref GetTwoDigitsBytesRef ( typeof ( TChar ) == typeof ( char ) ) , ( uint ) sizeof ( TChar ) * 2 * value ) ,
1576
1611
( uint ) sizeof ( TChar ) * 2 ) ;
1577
1612
}
1578
1613
@@ -1588,7 +1623,7 @@ internal static unsafe void WriteFourDigits<TChar>(uint value, TChar* ptr) where
1588
1623
1589
1624
( value , uint remainder ) = Math. DivRem ( value , 100 ) ;
1590
1625
1591
- ref byte charsArray = ref MemoryMarshal . GetReference ( typeof ( TChar ) == typeof ( char ) ? TwoDigitsCharsAsBytes : TwoDigitsBytes ) ;
1626
+ ref byte charsArray = ref GetTwoDigitsBytesRef ( typeof ( TChar ) == typeof ( char ) ) ;
1592
1627
1593
1628
Unsafe. CopyBlockUnaligned (
1594
1629
ref * ( byte * ) ptr ,
0 commit comments