ZaString 0.1.2
dotnet add package ZaString --version 0.1.2
NuGet\Install-Package ZaString -Version 0.1.2
<PackageReference Include="ZaString" Version="0.1.2" />
<PackageVersion Include="ZaString" Version="0.1.2" />
<PackageReference Include="ZaString" />
paket add ZaString --version 0.1.2
#r "nuget: ZaString, 0.1.2"
#:package ZaString@0.1.2
#addin nuget:?package=ZaString&version=0.1.2
#tool nuget:?package=ZaString&version=0.1.2
ZaString
ZaString is a high-performance, zero-allocation string manipulation library for C# that uses Span<T>
and
ReadOnlySpan<T>
for optimal memory efficiency. Built for .NET 9.0+, it provides a fluent API for building strings
without heap allocations.
๐ Key Features
- Zero Allocation: Stack-based string building with no heap allocations
- High Performance: Significantly faster than traditional
StringBuilder
- Fluent API: Chainable methods for intuitive string construction
- Type Safety: Full support for
ISpanFormattable
types with formatting - Memory Efficient: Uses stack-allocated buffers with precise capacity control
- UTF-8 Support: Built-in UTF-8 writer for byte-level operations
- Escape Helpers: JSON, HTML, CSV, and URL encoding utilities
- Interpolation Support: Custom interpolated string handlers
๐ฆ Installation
dotnet add package ZaString
๐ฏ Quick Start
using ZaString.Core;
using ZaString.Extensions;
// Create a stack-allocated buffer
Span<char> buffer = stackalloc char[100];
var builder = ZaSpanStringBuilder.Create(buffer);
// Build strings with fluent API
builder.Append("Hello, ")
.Append("World!")
.Append(" Number: ")
.Append(42)
.Append(" Pi: ")
.Append(Math.PI, "F2");
// Access result as span (zero allocation)
var result = builder.AsSpan();
Console.WriteLine(result); // "Hello, World! Number: 42 Pi: 3.14"
๐ง Core Components
ZaSpanStringBuilder
The main string builder that writes directly to a provided Span<char>
:
Span<char> buffer = stackalloc char[64];
var builder = ZaSpanStringBuilder.Create(buffer);
builder.Append("User: ")
.Append("John Doe")
.Append(", Age: ")
.Append(25)
.Append(", Active: ")
.Append(true);
// Access as ReadOnlySpan<char> (zero allocation)
var userInfo = builder.AsSpan();
ZaPooledStringBuilder
For scenarios requiring heap allocation with automatic buffer management:
using var builder = ZaPooledStringBuilder.Rent(128);
builder.Append("Pooled string building")
.Append(" with automatic cleanup");
var result = builder.ToString();
// Buffer automatically returned to pool when disposed
ZaUtf8SpanWriter
UTF-8 byte-level string writing:
Span<byte> buffer = stackalloc byte[256];
var writer = ZaUtf8SpanWriter.Create(buffer);
writer.Append("Hello, UTF-8 World!")
.Append(" Number: ")
.Append(123);
var utf8Bytes = writer.AsSpan();
๐จ Advanced Features
String Interpolation
var name = "Alice";
var age = 30;
var pi = Math.PI;
builder.Append($"User: {name}, Age: {age}, Pi: {pi:F2}");
Number Formatting
builder.Append("Currency: ")
.Append(1234.56, "C") // "$1,234.56"
.Append(", Number: ")
.Append(12345, "N0") // "12,345"
.Append(", Percentage: ")
.Append(0.85, "P2"); // "85.00%"
Culture-Specific Formatting
var fr = new CultureInfo("fr-FR");
builder.Append(1234.56, "C", fr); // "1 234,56 โฌ"
Conditional Appending
var isActive = true;
builder.Append("Status: ")
.AppendIf(isActive, "Active", "Inactive");
Escape Helpers
// JSON escaping
builder.AppendJsonEscaped("Line1\nLine2\t\"Quote\"");
// HTML escaping
builder.AppendHtmlEscaped("<script>alert('xss')</script>");
// URL encoding
builder.AppendUrlEncoded("Hello World!");
// CSV escaping
builder.AppendCsvEscaped("Value,with,commas");
URL Building
builder.AppendPathSegment("api")
.AppendPathSegment("v1")
.AppendPathSegment("users")
.AppendQueryParam("q", "search term", isFirst: true)
.AppendQueryParam("page", "1");
// Result: "api/v1/users?q=search%20term&page=1"
TryAppend Methods
Non-throwing variants for buffer overflow handling:
Span<char> smallBuffer = stackalloc char[10];
var builder = ZaSpanStringBuilder.Create(smallBuffer);
if (builder.TryAppend("Hello, World!"))
{
Console.WriteLine("Successfully appended");
}
else
{
Console.WriteLine("Buffer too small");
}
๐ Performance
ZaString significantly outperforms traditional string building approaches. Here are the actual benchmark results from comprehensive testing:
Basic String Building Performance
Method | Mean Time | Memory Allocations | Performance Ratio |
---|---|---|---|
StringBuilder (Baseline) |
146.1 ns | 480 B | 1.00x |
String concatenation |
116.3 ns | 248 B | 0.80x |
String interpolation |
116.9 ns | 136 B | 0.80x |
ZaSpanStringBuilder | 115.2 ns | 0 B | 0.79x |
Detailed Benchmark Results
Basic String Building:
StringBuilder
: 146.1 ns, 480 B allocatedStringConcatenation
: 116.3 ns, 248 B allocatedStringInterpolation
: 116.9 ns, 136 B allocated- ZaSpanStringBuilder: 115.2 ns, 0 B allocated โก
Number Formatting:
StringBuilder
: 295.3 ns, 584 B allocated- ZaSpanStringBuilder: 234.9 ns, 0 B allocated (20% faster)
Large String Operations:
StringBuilder
: 1,565.9 ns, 27,312 B allocated- ZaSpanStringBuilder: 1,236.5 ns, 0 B allocated (21% faster)
DateTime Formatting:
StringBuilder
: 189.0 ns, 384 B allocated- ZaSpanStringBuilder: 135.7 ns, 0 B allocated (28% faster)
Span vs String Processing:
StringBuilder
: 24.7 ns, 256 B allocated- ZaSpanStringBuilder: 10.4 ns, 0 B allocated (58% faster)
Number Formatting Performance using Builder
These results use a builder baseline (StringBuilder.AppendFormat with InvariantCulture) for apples-to-apples comparison against ZaSpanStringBuilder (zero allocation).
Case | Builder Mean | Builder Alloc | ZaSpan Mean | ZaSpan Alloc |
---|---|---|---|---|
Double | 128.70 ns | 176 B | 104.26 ns | 0 B |
Double (Formatted F2) | 94.20 ns | 160 B | 73.33 ns | 0 B |
Float | 105.12 ns | 168 B | 88.40 ns | 0 B |
Long | 27.51 ns | 176 B | 12.58 ns | 0 B |
Integer (Formatted N0) | 59.43 ns | 168 B | 38.28 ns | 0 B |
Environment: .NET 8.0.19, Ryzen 9 5950X, BenchmarkDotNet 0.15.2.
Key Performance Benefits
- Zero Memory Allocations: ZaSpanStringBuilder uses stack-allocated buffers
- 20-58% Faster: Significantly outperforms StringBuilder across most scenarios
- Predictable Performance: No GC pressure or memory fragmentation
- Scalable: Performance scales linearly with string size
- Memory Efficient: Up to 100% reduction in memory allocations
Benchmark Example
// Traditional approach - 146.1 ns, 480 B allocated
var sb = new StringBuilder();
sb.Append("Name: ").Append("John").Append(", Age: ").Append(25);
var result = sb.ToString();
// ZaString approach - 115.2 ns, 0 B allocated
Span<char> buffer = stackalloc char[50];
var builder = ZaSpanStringBuilder.Create(buffer);
builder.Append("Name: ").Append("John").Append(", Age: ").Append(25);
var result = builder.AsSpan(); // Zero allocation
๐ ๏ธ Use Cases
- High-frequency string operations in performance-critical applications
- Parsing and formatting without memory pressure
- HTTP response building in web servers
- Logging and diagnostics with minimal overhead
- Data serialization to avoid temporary allocations
- Real-time applications requiring predictable performance
๐ API Reference
Core Methods
Create(Span<char>)
- Create a new builder with a bufferAppend()
- Append various types with fluent APIAppendLine()
- Append with line terminatorTryAppend()
- Non-throwing append variantsAsSpan()
- Get result asReadOnlySpan<char>
ToString()
- Get result as string (allocates)Clear()
- Reset builder for reuseSetLength(int)
- Set current lengthRemoveLast(int)
- Remove characters from end
Extension Methods
AppendIf()
- Conditional appendingAppendJoin()
- Join collections with separatorsAppendRepeat()
- Repeat charactersAppendFormat()
- Composite formattingAppendJsonEscaped()
- JSON string escapingAppendHtmlEscaped()
- HTML entity escapingAppendUrlEncoded()
- URL percent encodingAppendCsvEscaped()
- CSV field escapingAppendPathSegment()
- URL path buildingAppendQueryParam()
- URL query parameter building
๐งช Testing
Run the comprehensive test suite:
dotnet test
Run performance benchmarks:
cd tests/ZaString.Benchmarks
dotnet run -c Release
๐ Examples
See the samples directory for complete working examples demonstrating all features.
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- Built with modern C# features and .NET 9.0
- Inspired by the performance benefits of
Span<T>
andMemory<T>
- Designed for zero-allocation scenarios in high-performance applications
Made with โค๏ธ for high-performance .NET applications
Product | Versions 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 was computed. 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. |
-
net8.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.