From 1b3c24bf74882d529c8a78ca73f9cb61a7e93eae Mon Sep 17 00:00:00 2001 From: mlemanczyk Date: Sat, 28 Jan 2023 23:48:28 +0100 Subject: [PATCH] Performance improvement - removed unneeded case. We never hit it in our benchmarks or tests. We'll use Memory instead of Span again, where applicable. --- Recyclable.Collections/RecyclableArrayList.cs | 36 ++--- Recyclable.Collections/RecyclableList.cs | 123 +++++++----------- 2 files changed, 59 insertions(+), 100 deletions(-) diff --git a/Recyclable.Collections/RecyclableArrayList.cs b/Recyclable.Collections/RecyclableArrayList.cs index 794d55b..581916f 100644 --- a/Recyclable.Collections/RecyclableArrayList.cs +++ b/Recyclable.Collections/RecyclableArrayList.cs @@ -21,38 +21,22 @@ namespace Recyclable.Collections { ArrayPool arrayPool = _arrayPool; var sourceLength = source?.Length ?? 0; - Span sourceSpan, newArraySpan; T[] newMemoryBlock = newSize >= RecyclableDefaults.MinPooledArrayLength ? arrayPool.Rent(newSize) : new T[newSize]; - switch (newSize >= sourceLength) + if (sourceLength > 0) { - case true: - if (sourceLength > 0) - { - sourceSpan = new Span(source); - newArraySpan = new Span(newMemoryBlock); - sourceSpan.CopyTo(newArraySpan); - if (sourceLength >= RecyclableDefaults.MinPooledArrayLength) - { - arrayPool.Return(source!); - } - } - - return newMemoryBlock; - - case false: - sourceSpan = new Span(source)[..newSize]; - newArraySpan = new(newMemoryBlock); - sourceSpan.CopyTo(newArraySpan); - if (sourceLength >= RecyclableDefaults.MinPooledArrayLength) - { - arrayPool.Return(source!); - } - - return newMemoryBlock; + var sourceSpan = new Memory(source); + var newArraySpan = new Memory(newMemoryBlock); + sourceSpan.CopyTo(newArraySpan); + if (sourceLength >= RecyclableDefaults.MinPooledArrayLength) + { + arrayPool.Return(source!); + } } + + return newMemoryBlock; } protected int EnsureCapacity(in int requestedCapacity) diff --git a/Recyclable.Collections/RecyclableList.cs b/Recyclable.Collections/RecyclableList.cs index 9d732ee..b6dd393 100644 --- a/Recyclable.Collections/RecyclableList.cs +++ b/Recyclable.Collections/RecyclableList.cs @@ -88,89 +88,64 @@ namespace Recyclable.Collections ? arrayPool.Rent(requiredBlockCount) : new T[requiredBlockCount][]; - switch (requiredBlockCount >= sourceBlockCount) + switch (sourceBlockCount > 0) { case true: - switch (sourceBlockCount > 0) - { - case true: - sourceSpan = new Span(source); - newArraySpan = new Span(newMemoryBlocks); - sourceSpan.CopyTo(newArraySpan); - if (sourceSpan.Length >= RecyclableDefaults.MinPooledArrayLength) - { - arrayPool.Return(source!); - } - - newArraySpan = newArraySpan[sourceBlockCount..]; - break; - - case false: - newArraySpan = new Span(newMemoryBlocks); - break; - } - - int uninitializedBlocksCount = newArraySpan.Length; - if (uninitializedBlocksCount == requiredBlockCount) - { - switch (blockSize >= RecyclableDefaults.MinPooledArrayLength) - { - case true: - newArraySpan[0] = blockArrayPool.Rent(blockSize); - blockSize = newArraySpan[0].Length; - break; - - case false: - newArraySpan[0] = new T[blockSize]; - break; - } - - newArraySpan = newArraySpan[1..]; - uninitializedBlocksCount--; - } - - switch (blockSize >= RecyclableDefaults.MinPooledArrayLength) - { - case true: - for (int i = 0; i < uninitializedBlocksCount; i++) - { - newArraySpan[i] = blockArrayPool.Rent(blockSize); - } - - break; - - case false: - for (int i = 0; i < uninitializedBlocksCount; i++) - { - newArraySpan[i] = new T[blockSize]; - } - - break; - } - - return newMemoryBlocks; - - case false: - sourceSpan = new Span(source)[..requiredBlockCount]; + sourceSpan = new Span(source); newArraySpan = new Span(newMemoryBlocks); sourceSpan.CopyTo(newArraySpan); - sourceSpan = new Span(source)[newArraySpan.Length..]; - int sourceLength = sourceSpan.Length; - if (blockSize >= RecyclableDefaults.MinPooledArrayLength) - { - for (int i = 0; i < sourceLength; i++) - { - blockArrayPool.Return(sourceSpan[i]); - } - } - - if (sourceLength >= RecyclableDefaults.MinPooledArrayLength) + if (sourceSpan.Length >= RecyclableDefaults.MinPooledArrayLength) { arrayPool.Return(source!); } - return newMemoryBlocks; + newArraySpan = newArraySpan[sourceBlockCount..]; + break; + + case false: + newArraySpan = new Span(newMemoryBlocks); + break; } + + int uninitializedBlocksCount = newArraySpan.Length; + if (uninitializedBlocksCount == requiredBlockCount) + { + switch (blockSize >= RecyclableDefaults.MinPooledArrayLength) + { + case true: + newArraySpan[0] = blockArrayPool.Rent(blockSize); + blockSize = newArraySpan[0].Length; + break; + + case false: + newArraySpan[0] = new T[blockSize]; + break; + } + + newArraySpan = newArraySpan[1..]; + uninitializedBlocksCount--; + } + + switch (blockSize >= RecyclableDefaults.MinPooledArrayLength) + { + case true: + for (int i = 0; i < uninitializedBlocksCount; i++) + { + newArraySpan[i] = blockArrayPool.Rent(blockSize); + } + + break; + + case false: + for (int i = 0; i < uninitializedBlocksCount; i++) + { + newArraySpan[i] = new T[blockSize]; + } + + break; + } + + return newMemoryBlocks; } protected long EnsureCapacity(in long requestedCapacity)