Skip to content

Commit

Permalink
Add a couple common type sizes to SegmentedArrayHelper's size/shift/o…
Browse files Browse the repository at this point in the history
…ffsetmask methods so those values can be inlined. (#75944)

This isn't super significant, but about 175ms of CPU are accounted for these methods in the scrolling speedometer test in our OOP. I believe those should go away completely as these are the only common values that weren't already being handled when I manually debugged the product.
  • Loading branch information
ToddGrun authored Nov 21, 2024
1 parent d7b111f commit 5da7e94
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ namespace Microsoft.CodeAnalysis.UnitTests.Collections
{
public class SegmentedArrayHelperTests
{
[StructLayout(LayoutKind.Sequential, Size = 1)]
private struct Size1 { }

[StructLayout(LayoutKind.Sequential, Size = 2)]
private struct Size2 { }

Expand Down Expand Up @@ -44,10 +47,14 @@ private struct Size32 { }
[StructLayout(LayoutKind.Sequential, Size = 40)]
private struct Size40 { }

[StructLayout(LayoutKind.Sequential, Size = 64)]
private struct Size64 { }

public static IEnumerable<object[]> ExplicitSizeTypes
{
get
{
yield return new object[] { typeof(Size1) };
yield return new object[] { typeof(Size2) };
yield return new object[] { typeof(Size4) };
yield return new object[] { typeof(Size8) };
Expand All @@ -57,6 +64,7 @@ public static IEnumerable<object[]> ExplicitSizeTypes
yield return new object[] { typeof(Size28) };
yield return new object[] { typeof(Size32) };
yield return new object[] { typeof(Size40) };
yield return new object[] { typeof(Size64) };
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/Dependencies/Collections/Internal/SegmentedArrayHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ internal static int GetSegmentSize<T>()
// Hard code common values since not all versions of the .NET JIT support reducing this computation to a
// constant value at runtime. Values are validated against the reference implementation in
// CalculateSegmentSize in unit tests.
1 => 65536,
2 => 32768,
4 => 16384,
8 => 8192,
12 => 4096,
Expand All @@ -31,6 +33,7 @@ internal static int GetSegmentSize<T>()
28 => 2048,
32 => 2048,
40 => 2048,
64 => 1024,
#if NETCOREAPP3_0_OR_GREATER
_ => InlineCalculateSegmentSize(Unsafe.SizeOf<T>()),
#else
Expand All @@ -47,6 +50,8 @@ internal static int GetSegmentShift<T>()
// Hard code common values since not all versions of the .NET JIT support reducing this computation to a
// constant value at runtime. Values are validated against the reference implementation in
// CalculateSegmentSize in unit tests.
1 => 16,
2 => 15,
4 => 14,
8 => 13,
12 => 12,
Expand All @@ -55,6 +60,7 @@ internal static int GetSegmentShift<T>()
28 => 11,
32 => 11,
40 => 11,
64 => 10,
#if NETCOREAPP3_0_OR_GREATER
_ => InlineCalculateSegmentShift(Unsafe.SizeOf<T>()),
#else
Expand All @@ -71,6 +77,8 @@ internal static int GetOffsetMask<T>()
// Hard code common values since not all versions of the .NET JIT support reducing this computation to a
// constant value at runtime. Values are validated against the reference implementation in
// CalculateSegmentSize in unit tests.
1 => 65535,
2 => 32767,
4 => 16383,
8 => 8191,
12 => 4095,
Expand All @@ -79,6 +87,7 @@ internal static int GetOffsetMask<T>()
28 => 2047,
32 => 2047,
40 => 2047,
64 => 1023,
#if NETCOREAPP3_0_OR_GREATER
_ => InlineCalculateOffsetMask(Unsafe.SizeOf<T>()),
#else
Expand Down

0 comments on commit 5da7e94

Please sign in to comment.