Optimize memory allocation in ALMA and Conv classes; improve performance by using stackalloc for small periods

This commit is contained in:
Miha Kralj
2025-12-10 15:15:20 -05:00
parent 47884bddab
commit 81830c9031
3 changed files with 8 additions and 15 deletions
+2 -2
View File
@@ -210,7 +210,8 @@ public sealed class Alma : ITValuePublisher
throw new ArgumentException("Source and output must have the same length"); throw new ArgumentException("Source and output must have the same length");
// Precompute weights // Precompute weights
double[] weights = new double[period]; // Use stackalloc for small periods to avoid heap allocation
Span<double> weights = period <= 256 ? stackalloc double[period] : new double[period];
double m = offset * (period - 1); double m = offset * (period - 1);
double s = period / sigma; double s = period / sigma;
double s2 = 2 * s * s; double s2 = 2 * s * s;
@@ -224,7 +225,6 @@ public sealed class Alma : ITValuePublisher
} }
// Buffer for sliding window // Buffer for sliding window
// Use stackalloc for small periods
Span<double> buffer = period <= 256 ? stackalloc double[period] : new double[period]; Span<double> buffer = period <= 256 ? stackalloc double[period] : new double[period];
int bufferIdx = 0; int bufferIdx = 0;
int count = 0; int count = 0;
+5 -10
View File
@@ -26,7 +26,6 @@ public sealed class Conv : ITValuePublisher
private readonly RingBuffer _buffer; private readonly RingBuffer _buffer;
private double _lastValidValue; private double _lastValidValue;
private int _head;
// State for bar correction // State for bar correction
private double _p_lastValidValue; private double _p_lastValidValue;
@@ -83,7 +82,6 @@ public sealed class Conv : ITValuePublisher
if (isNew) if (isNew)
{ {
_buffer.Add(val); _buffer.Add(val);
_head = (_head + 1 == _period) ? 0 : _head + 1;
} }
else else
{ {
@@ -104,10 +102,11 @@ public sealed class Conv : ITValuePublisher
} }
else else
{ {
// Full: data is split at _head (which points to oldest) // Full: data is split at StartIndex (which points to oldest)
int part1Len = _period - _head; int head = _buffer.StartIndex;
result = internalBuf.Slice(_head, part1Len).DotProduct(kernelSpan.Slice(0, part1Len)) int part1Len = _period - head;
+ internalBuf.Slice(0, _head).DotProduct(kernelSpan.Slice(part1Len)); result = internalBuf.Slice(head, part1Len).DotProduct(kernelSpan.Slice(0, part1Len))
+ internalBuf.Slice(0, head).DotProduct(kernelSpan.Slice(part1Len));
} }
} }
@@ -165,9 +164,6 @@ public sealed class Conv : ITValuePublisher
_buffer.Add(val); _buffer.Add(val);
} }
// Sync _head with buffer state
_head = windowSize % _period;
// Set Last // Set Last
Last = new TValue(source.Times[len - 1], vSpan[len - 1]); Last = new TValue(source.Times[len - 1], vSpan[len - 1]);
@@ -247,7 +243,6 @@ public sealed class Conv : ITValuePublisher
_buffer.Clear(); _buffer.Clear();
_lastValidValue = double.NaN; _lastValidValue = double.NaN;
_p_lastValidValue = double.NaN; _p_lastValidValue = double.NaN;
_head = 0;
Last = default; Last = default;
} }
} }
+1 -3
View File
@@ -421,9 +421,7 @@ public sealed class Wma : ITValuePublisher
var vSums = Avx.Add(vSumState, vPS2); var vSums = Avx.Add(vSumState, vPS2);
var vSumsShifted = Avx2.Permute4x64(vSums.AsUInt64(), 0b_10_01_00_00).AsDouble(); // skipcq: CS-R1131 var vSumsShifted = Avx.Subtract(vSums, vDeltaS);
vSumsShifted = Avx.Blend(vSumState, vSumsShifted, 0b_1110);
var vTerm1 = Avx.Multiply(vPeriod, vNew); var vTerm1 = Avx.Multiply(vPeriod, vNew);
var vU = Avx.Subtract(vTerm1, vSumsShifted); var vU = Avx.Subtract(vTerm1, vSumsShifted);