Woggle 2.0.3
dotnet add package Woggle --version 2.0.3
NuGet\Install-Package Woggle -Version 2.0.3
<PackageReference Include="Woggle" Version="2.0.3" />
<PackageVersion Include="Woggle" Version="2.0.3" />
<PackageReference Include="Woggle" />
paket add Woggle --version 2.0.3
#r "nuget: Woggle, 2.0.3"
#:package Woggle@2.0.3
#addin nuget:?package=Woggle&version=2.0.3
#tool nuget:?package=Woggle&version=2.0.3
Woggle
Woggle is a .NET library that provides high-performance, memory-efficient collections using ArrayPool<T> to reduce garbage collection pressure and improve the performance of your applications.
Key Features
- Reduce Memory Allocation by up to 99%: Woggle's pooled collections can slash memory allocations by up to 99% compared to standard .NET collections, significantly reducing pressure on the garbage collector.
- Pooled Collections: Provides two main high-performance, disposable collection types:
PooledList<T>: A resizable list implementation, similar toList<T>, but backed by a rented array that automatically expands capacity as needed.PooledArray<T>: A fixed-size array wrapper, designed for highly efficient, span-based operations on a pre-allocated array segment.
- Span Integration: Both collections are fully integrated with modern .NET primitives, offering explicit conversion operators to
Span<T>andReadOnlySpan<T>for zero-allocation memory access and manipulation. - Convenience Extensions: Easily convert existing .NET collections, arrays, and spans into pooled variants using extension methods like
ToPooledArray()andToPooledList().
Getting Started
You can install the library through the NuGet Package Manager:
Install-Package Woggle
Using PooledList<T>
The PooledList<T> is a versatile, mutable list that's perfect for when you need a dynamic collection but want to avoid the memory overhead of a standard List<T>.
Here is how you can use PooledList<T> in your project:
using Woggle;
using System;
using System.Buffers;
// Create a new PooledList with a default capacity
using var pooledList = new PooledList<int>();
// Add items to the list
pooledList.Add(10);
pooledList.Add(20);
pooledList.Add(30);
// Access elements by index
Console.WriteLine(pooledList[1]); // Output: 20
// The underlying array is automatically returned to the pool when disposed
Using PooledArray<T>
PooledArray<T> is a fixed-size structure, and attempts to modify its length (e.g., calling Add or Remove) will throw a NotSupportedException.
using Woggle;
using System.Buffers;
// Rents an array of the specified length (5) from the pool.
using (var pooledArray = new PooledArray<string>(5))
{
pooledArray[0] = "Hello";
pooledArray[1] = "Woggle";
// Access the contents as a span
ReadOnlySpan<string> span = pooledArray.AsSpan();
Console.WriteLine($"Length: {pooledArray.Length}"); // Output: Length: 5
// Implicit conversion to Span<T>
Span<string> arraySpan = pooledArray;
// arraySpan is a Span<string> over the entire rented array segment.
} // The rented array is automatically returned to the pool here.
Effortless Conversion with Extension Methods
Woggle's CollectionExtensions make it incredibly easy to convert your existing collections into pooled collections.
using Woggle;
using System;
using System.Collections.Generic;
// Convert a standard List<T> to a PooledList<T>
var originalList = new List<int> { 100, 200, 300 };
using var pooledListFromList = originalList.ToPooledList();
Console.WriteLine(pooledListFromList.Count); // Output: 3
// Convert an array to a PooledArray<T>
var originalArray = new[] { 5, 10, 15, 20 };
using var pooledArrayFromArray = originalArray.ToPooledArray();
Console.WriteLine(pooledArrayFromArray[1]); // Output: 10
Working with Span<T> for High-Performance Scenarios
PooledArray<T> can be implicitly converted to Span<T> and ReadOnlySpan<T>, enabling you to work with them in high-performance, allocation-free APIs.
using Woggle;
using System;
void ProcessData(Span<int> data)
{
for (int i = 0; i < data.Length; i++)
{
data[i] *= 2;
}
}
using var list = new PooledList<int> { 1, 2, 3 };
// Implicitly convert PooledList<T> to Span<T>
ProcessData(list.AsSpan());
foreach (var item in list)
{
Console.WriteLine(item); // Output: 2, 4, 6
}
Custom ArrayPool<T> Support
For advanced scenarios, you can provide your own instance of ArrayPool<T> to have more control over the memory pooling behavior.
using Woggle;
using System;
using System.Buffers;
// Create a custom ArrayPool
var customPool = ArrayPool<int>.Create();
// Use the custom pool with PooledList
using var pooledListWithCustomPool = new PooledList<int>(customPool);
pooledListWithCustomPool.Add(15);
// Use the custom pool with the extension methods
var data = new[] { 1, 2, 3 };
using var pooledArrayWithCustomPool = data.ToPooledArray(customPool);
Benchmarks
These benchmarks were run on Windows 11 using a AMD Ryzen 7 5700G processor at 3.80GHz. Package version 2.0.3.
Pooled List
| Method | N | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|---|---|
| List_Add | 100 | 189.1 ns | 3.32 ns | 3.11 ns | 1.00 | 0.02 | 0.1414 | 0.0002 | 1184 B | 1.00 |
| PooledList_Add | 100 | 174.4 ns | 1.51 ns | 1.41 ns | 0.92 | 0.02 | 0.0048 | - | 40 B | 0.03 |
| List_Iterate | 100 | 143.4 ns | 1.98 ns | 1.86 ns | 0.76 | 0.02 | 0.0544 | - | 456 B | 0.39 |
| PooledList_Iterate | 100 | 266.7 ns | 1.22 ns | 1.08 ns | 1.41 | 0.02 | 0.0095 | - | 80 B | 0.07 |
| List_Add | 1000 | 1,169.2 ns | 22.66 ns | 20.09 ns | 1.00 | 0.02 | 1.0052 | - | 8424 B | 1.000 |
| PooledList_Add | 1000 | 1,116.7 ns | 2.36 ns | 2.21 ns | 0.96 | 0.02 | 0.0038 | - | 40 B | 0.005 |
| List_Iterate | 1000 | 1,328.3 ns | 13.50 ns | 12.62 ns | 1.14 | 0.02 | 0.4845 | - | 4056 B | 0.481 |
| PooledList_Iterate | 1000 | 2,243.0 ns | 7.08 ns | 6.28 ns | 1.92 | 0.03 | 0.0076 | - | 80 B | 0.009 |
Pooled Array
| Method | N | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|---|---|
| Array_CreateAndFill | 100 | 36.44 ns | 0.630 ns | 0.589 ns | 36.65 ns | 1.00 | 0.02 | 0.0507 | 424 B | 1.00 |
| PooledArray_CreateAndFill | 100 | 82.91 ns | 0.372 ns | 0.348 ns | 82.88 ns | 2.28 | 0.04 | 0.0048 | 40 B | 0.09 |
| Array_CreateAndFill | 1000 | 329.01 ns | 6.483 ns | 17.305 ns | 320.91 ns | 1.00 | 0.07 | 0.4807 | 4024 B | 1.000 |
| PooledArray_CreateAndFill | 1000 | 501.94 ns | 1.015 ns | 0.848 ns | 501.82 ns | 1.53 | 0.07 | 0.0048 | 40 B | 0.010 |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Woggle:
| Package | Downloads |
|---|---|
|
Woggle.Benchmarks
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.