KZDev.PerfUtils 3.0.1

Prefix Reserved
dotnet add package KZDev.PerfUtils --version 3.0.1
                    
NuGet\Install-Package KZDev.PerfUtils -Version 3.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="KZDev.PerfUtils" Version="3.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="KZDev.PerfUtils" Version="3.0.1" />
                    
Directory.Packages.props
<PackageReference Include="KZDev.PerfUtils" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add KZDev.PerfUtils --version 3.0.1
                    
#r "nuget: KZDev.PerfUtils, 3.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package KZDev.PerfUtils@3.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=KZDev.PerfUtils&version=3.0.1
                    
Install as a Cake Addin
#tool nuget:?package=KZDev.PerfUtils&version=3.0.1
                    
Install as a Cake Tool

KZDev.PerfUtils

The KZDev.PerfUtils package provides the following high-performance utility classes:

  • MemoryStreamSlim: A high-performance, memory-efficient stream for large or frequently resized in-memory buffers, modeled on MemoryStream with a largely compatible API.
  • StringBuilderCache: A thread-safe cache of StringBuilder instances to improve speed and reduce the overhead of memory allocations associated with the StringBuilder class.
  • InterlockedOps: A utility that extends the functionality of the Interlocked class in the .NET Class Library by providing additional atomic thread-safe operations.

Important: MemoryStreamSlim outperforms RecyclableMemoryStream across all benchmarked categories in this project.

New in v3: MemoryStreamSlim.ToMemory() introduces a significantly more memory-efficient way to access raw stream buffers as Memory<byte>.

Supported target frameworks

This package targets .NET 8 (net8.0), .NET 9 (net9.0), and .NET 10 (net10.0). The 3.x line does not ship builds for older TFMs (including .NET 6); upgrade consuming projects to a supported target framework before referencing the latest package versions.

Performance Highlights

This sampling of performance benchmarks clearly demonstrates the advantages of using the KZDev.PerfUtils package:

StringBuilderCache Performance Sample

MemoryStreamSlim Performance Sample

For more details, refer to the benchmark related pages in the documentation.

Features

MemoryStreamSlim

MemoryStreamSlim targets workloads where MemoryStream limits throughput or drives high GC cost. It is largely API-compatible with MemoryStream, so many call sites can switch the concrete type with small edits, but it is not guaranteed to match MemoryStream in every behavioral edge case. Construct instances with MemoryStreamSlim.Create (and related overloads) instead of new MemoryStream. After Dispose, Length, Position, and capacity-related members follow the same ObjectDisposedException rules as MemoryStream; do not rely on reading those values from a disposed stream.

  • Improved Throughput: Outperforms the standard MemoryStream.
  • Reduced Memory Traffic: Significantly lowers memory traffic and garbage collection compared to the standard MemoryStream.
  • Eliminates LOH Fragmentation: Prevents Large Object Heap (LOH) fragmentation caused by frequent use and release of single-byte arrays.
  • Optional Native Memory Storage: Allows the use of native memory for storage, further reducing GC pressure and increasing flexibility.
  • Outperforms Similar Libraries: Compared to other libraries like RecyclableMemoryStream, it is designed to be easier to use, more flexible, and incurs fewer memory allocations and garbage collections.

StringBuilderCache

StringBuilderCache is a static class that provides a thread-safe cache of StringBuilder instances, reducing allocations and deallocations in high-throughput scenarios. Key features include:

  • Acquire: Retrieve a StringBuilder instance from the cache.
  • Release: Return a StringBuilder instance to the cache.
  • GetStringAndRelease: Retrieve the string from a StringBuilder instance and return it to the cache.
  • GetScope: Use a using-scoped StringBuilder instance, which is automatically returned to the cache when the scope is exited.
  • Monitoring: Leverages the .NET runtime's Events feature for detailed cache management and monitoring.

InterlockedOps

InterlockedOps is a static class that provides additional thread-safe atomic operations for integer types, including:

  • Xor: Perform an exclusive OR operation.
  • ClearBits: Clear specific bits.
  • SetBits: Set specific bits.
  • ConditionAnd: Conditionally update bits using an AND operation.
  • ConditionOr: Conditionally update bits using an OR operation.
  • ConditionXor: Conditionally update bits using an XOR operation.
  • ConditionClearBits: Conditionally clear specific bits.
  • ConditionSetBits: Conditionally set specific bits.

Examples

MemoryStreamSlim Example

Below is an example of how to use the MemoryStreamSlim class. Use the Create methods for construction; the member surface area matches MemoryStream for supported APIs, with behavioral differences documented for disposed streams and advanced options. Dispose the MemoryStreamSlim instance when it is no longer needed.

using KZDev.PerfUtils;

// Create a new MemoryStreamSlim instance
// For the best management of the memory buffers, it is very important to
// dispose of the MemoryStreamSlim instance when it is no longer needed.
using (MemoryStreamSlim stream = MemoryStreamSlim.Create())
{
        // Write some data to the stream
        stream.Write(new byte[] { 1, 2, 3, 4, 5 }, 0, 5);

        // Read the data back from the stream
        stream.Position = 0;
        byte[] buffer = new byte[5];
        stream.Read(buffer, 0, 5);
}

StringBuilderCache Example

Below is an example of how to use the StringBuilderCache class to acquire a StringBuilder instance, append strings to it, and then release it back to the cache. The GetStringAndRelease method is used to retrieve the string and release the StringBuilder instance back to the cache.

using KZDev.PerfUtils;

class Program
{
    static void Main()
    {
        StringBuilder stringBuilder = StringBuilderCache.Acquire();
        stringBuilder.Append("Hello, ");
        stringBuilder.Append("World!");
        Console.WriteLine(StringBuilderCache.GetStringAndRelease(stringBuilder));
    }
}

InterlockedOps Example

Below is an example of how to use the InterlockedOps class to perform an atomic XOR operation on an integer variable. The Xor method toggles a bit flag between 1 and 0 in a thread-safe manner and returns a boolean value indicating whether the bit flag was set to 1.

using KZDev.PerfUtils;

public class XorExample
{
    private int _flag;

    public bool ToggleFlag ()
    {
        int originalValue = InterlockedOps.Xor(ref _flag, 1);
        return originalValue == 0;
    }
}

Compare to RecyclableMemoryStream

The MemoryStreamSlim class is conceptually similar to the RecyclableMemoryStream class from Microsoft. However, the internal implementation of buffer management is quite different. Compared to RecyclableMemoryStream, the MemoryStreamSlim class is designed to:

  • Easier to use without requiring parameter tuning.
  • More flexible across a broad range of use cases.
  • Fewer memory allocations and garbage collections.
  • Consistent performance across workloads.
  • Security-first design with opt-out zeroing of unused memory.
  • Automatic memory trimming and release.
  • Supports .NET Metrics and Events for monitoring.
  • Optionally uses native memory to avoid GC pressure.

Performance comparisons are also available in the benchmarks documentation section.

Documentation

Comprehensive documentation for the package is available on the PerfUtils Documentation page.

Future Features

The roadmap for this package includes plans to add additional performance-focused utilities as time permits.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.1 86 4/16/2026
3.0.0 87 4/14/2026
2.0.1 293 5/1/2025
2.0.0 250 4/23/2025
1.2.0 241 1/3/2025
1.1.0 219 10/25/2024
1.0.0 207 10/13/2024

3.0.1: Major release for target framework alignment. Supported target frameworks are net8.0, net9.0, and net10.0. Support for .NET 6 has been removed; upgrade consuming projects to a supported framework. Revision release to fix some incorrect base class method access modifiers. Breaking (dynamic-mode MemoryStreamSlim): after Dispose, Length and Position getters/setters and capacity APIs (Capacity, CapacityLong) throw ObjectDisposedException where aligned with BCL MemoryStream; code that relied on non-throwing reads of last values after dispose must change—see ReleaseNotes.md. Prior 2.x highlights included .NET 9 support, MemoryStreamSlim Int64 capacity, compression stream helpers (2.0.0), and a race-condition fix (2.0.1).