From 25bf466f77e4f6ec73792d24bdf931f778b46c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Lema=C5=84czyk?= Date: Mon, 14 Jul 2025 23:02:13 +0200 Subject: [PATCH] Optimize indexing helpers --- .../RecyclableLongList.Helpers.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Recyclable.Collections/RecyclableLongList.Helpers.cs b/Recyclable.Collections/RecyclableLongList.Helpers.cs index 6015f77..61dc9d7 100644 --- a/Recyclable.Collections/RecyclableLongList.Helpers.cs +++ b/Recyclable.Collections/RecyclableLongList.Helpers.cs @@ -1,4 +1,5 @@ using Recyclable.Collections.Pools; +using System.Numerics; using System.Runtime.CompilerServices; namespace Recyclable.Collections @@ -76,11 +77,11 @@ namespace Recyclable.Collections return; } - ReadOnlySpan sourceBlockMemory; - Span destinationArrayMemory; - // TODO: Replace with bit-shifting - int startingBlockIndex = (int)(startingIndex / blockSize); - int lastBlockIndex = (int)((itemsCount / blockSize) + (itemsCount % blockSize != 0 ? 1 : 0)) - 1; + ReadOnlySpan sourceBlockMemory; + Span destinationArrayMemory; + int blockSizePow2Shift = BitOperations.TrailingZeroCount((uint)blockSize); + int startingBlockIndex = (int)(startingIndex >> blockSizePow2Shift); + int lastBlockIndex = (int)((itemsCount >> blockSizePow2Shift) + ((itemsCount & (blockSize - 1)) != 0 ? 1 : 0)) - 1; ReadOnlySpan sourceMemoryBlocksSpan = new(sourceMemoryBlocks, startingBlockIndex, lastBlockIndex + 1); destinationArrayMemory = new Span(destinationArray, destinationArrayIndex, (int)Math.Min(destinationArray.Length - destinationArrayIndex, itemsCount)); int memoryBlockIndex; @@ -105,9 +106,9 @@ namespace Recyclable.Collections return; } - // TODO: Replace with bit-shifting - int startingBlockIndex = (int)(startingIndex / blockSize); - int lastBlockIndex = (int)((itemsCount / blockSize) + (itemsCount % blockSize != 0 ? 1 : 0)) - 1; + int blockSizePow2Shift = BitOperations.TrailingZeroCount((uint)blockSize); + int startingBlockIndex = (int)(startingIndex >> blockSizePow2Shift); + int lastBlockIndex = (int)((itemsCount >> blockSizePow2Shift) + ((itemsCount & (blockSize - 1)) != 0 ? 1 : 0)) - 1; var destinationIndex = destinationArrayIndex; ReadOnlySpan sourceMemoryBlocksSpan = new(sourceMemoryBlocks, startingBlockIndex, lastBlockIndex + 1);