Skip to content

Commit

Permalink
BitHelper with uint division and without Math.DivRem for even better …
Browse files Browse the repository at this point in the history
…codegen

AggressiveInlining isn't needed anymore, also the JIT recognizes the _span field, so no local Span is needed here.
  • Loading branch information
gfoidl committed Apr 4, 2022
1 parent da31c0b commit 7e816a5
Showing 1 changed file with 6 additions and 11 deletions.
17 changes: 6 additions & 11 deletions src/libraries/Common/src/System/Collections/Generic/BitHelper.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;

namespace System.Collections.Generic
{
internal ref struct BitHelper
Expand All @@ -21,22 +19,19 @@ internal BitHelper(Span<int> span, bool clear)

internal void MarkBit(int bitPosition)
{
(uint bitArrayIndex, uint position) = Math.DivRem((uint)bitPosition, IntSize);
Span<int> span = _span;
if (bitArrayIndex < (uint)span.Length)
uint bitArrayIndex = (uint)bitPosition / IntSize;
if (bitArrayIndex < (uint)_span.Length)
{
span[(int)bitArrayIndex] |= 1 << (int)position;
_span[(int)bitArrayIndex] |= (1 << (int)((uint)bitPosition % IntSize));
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal bool IsMarked(int bitPosition)
{
(uint bitArrayIndex, uint position) = Math.DivRem((uint)bitPosition, IntSize);
Span<int> span = _span;
uint bitArrayIndex = (uint)bitPosition / IntSize;
return
bitArrayIndex < (uint)span.Length &&
(span[(int)bitArrayIndex] & (1 << (int)position)) != 0;
bitArrayIndex < (uint)_span.Length &&
(_span[(int)bitArrayIndex] & ((int)((uint)bitPosition % IntSize))) != 0;
}

/// <summary>How many ints must be allocated to represent n bits. Returns (n+31)/32, but avoids overflow.</summary>
Expand Down

0 comments on commit 7e816a5

Please sign in to comment.