Add Span API for SMA, EMA, and WMA with zero-allocation performance improvements

- Implemented zero-allocation methods for SMA, EMA, and WMA calculations using ReadOnlySpan and Span.
- Added unit tests for Span API to validate input, match TSeries calculations, handle NaN values, and ensure zero allocation.
- Enhanced documentation to include usage examples for the new Span API.
- Introduced performance benchmarks comparing the new Span API against existing TSeries implementations and other libraries.
This commit is contained in:
Miha Kralj
2025-11-29 20:48:01 -08:00
parent 5c1fb18520
commit 2d28b8f62a
12 changed files with 936 additions and 3 deletions
+29 -1
View File
@@ -67,11 +67,39 @@ Console.WriteLine($"Name: {sma.Name}"); // "Sma(10)"
Console.WriteLine($"WarmupPeriod: {sma.WarmupPeriod}"); // 10
Console.WriteLine($"IsHot: {sma.IsHot}"); // true when buffer is full
// Batch calculation
// Batch calculation (TSeries API)
TSeries source = ...;
TSeries results = Sma.Calculate(source, 10);
// High-performance Span API (zero allocation)
double[] prices = new double[10000];
double[] output = new double[10000];
Sma.Calculate(prices.AsSpan(), output.AsSpan(), period: 10);
```
### Zero-Allocation Span API
For performance-critical scenarios (backtesting, HFT), use the Span-based overload:
```csharp
// Allocate buffers once, reuse across calculations
double[] source = new double[200000];
double[] smaOutput = new double[200000];
// Zero heap allocation during calculation
Sma.Calculate(source.AsSpan(), smaOutput.AsSpan(), period: 100);
// Results are written directly to output buffer
Console.WriteLine($"Last SMA: {smaOutput[^1]}");
```
**Benefits:**
* **Zero allocation**: No GC pressure during calculation
* **Cache-friendly**: Sequential memory access patterns
* **2-3x faster** than TSeries API for large datasets
* **Compatible** with `ArrayPool<T>` for buffer management
### Multi-Period SMA (`SmaVector`)
The `SmaVector` class calculates multiple SMAs with different periods on the same input series simultaneously.