Skip to content

Commit

Permalink
Improved performance of Select (Value) node by using arrays directly …
Browse files Browse the repository at this point in the history
…and removing output slice count by using new DynamicOutputWriter class.
  • Loading branch information
azeno committed Feb 10, 2014
1 parent 3018178 commit 54744cc
Showing 1 changed file with 52 additions and 54 deletions.
106 changes: 52 additions & 54 deletions vvvv45/src/nodes/plugins/_SpreadOperations/SelectNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,79 +25,77 @@ public void Evaluate(int spreadMax)
if (!StreamUtils.AnyChanged(FDataIn, FSelectIn)) return;
spreadMax = StreamUtils.GetSpreadMax(FDataIn, FSelectIn);

// Compute the output length
var outputLength = 0;
var selectLength = FSelectIn.Length;
if (selectLength > 0)
// Early exit
if (spreadMax == 0)
{
var selectSum = FSelectIn.Sum();
var remainder = 0;
var numSlicesPerSelect = Math.DivRem(spreadMax, selectLength, out remainder);
outputLength = selectSum * numSlicesPerSelect;
if (remainder > 0)
outputLength += FSelectIn.Take(remainder).Sum();
FDataOut.Length = 0;
FFormerSliceOut.Length = 0;
return;
}

// Set the length of the outputs
FDataOut.Length = outputLength;
FFormerSliceOut.Length = outputLength;

// Early exit
if (outputLength == 0) return;

// Fetch readers and writers
using (var dataReader = FDataIn.GetCyclicReader())
using (var selectReader = FSelectIn.GetCyclicReader())
using (var dataWriter = FDataOut.GetWriter())
using (var formerSliceWriter = FFormerSliceOut.GetWriter())
// Grab buffers from pool
using (var dataInBuffer = MemoryPool<T>.GetBuffer())
using (var dataOutBuffer = MemoryPool<T>.GetBuffer())
using (var selectBuffer = MemoryPool<int>.GetBuffer())
using (var sliceBuffer = MemoryPool<int>.GetBuffer())
using (var dataWriter = FDataOut.GetDynamicWriter())
using (var formerSliceWriter = FFormerSliceOut.GetDynamicWriter())
{
var numSlicesToRead = spreadMax;
var offset = 0;
var formerSlice = 0;
while (numSlicesToRead > 0)
// Grab buffers from pool
var dataInBuffer = MemoryPool<T>.GetArray();
var dataOutBuffer = MemoryPool<T>.GetArray();
var selectBuffer = MemoryPool<int>.GetArray();
var sliceBuffer = MemoryPool<int>.GetArray();
try
{
var blockSize = Math.Min(StreamUtils.BUFFER_SIZE, numSlicesToRead);
dataReader.Read(dataInBuffer.Array, 0, blockSize);
selectReader.Read(selectBuffer.Array, 0, blockSize);

// This loop iterates through the input data
for (int i = 0; i < blockSize; i++)
var numSlicesToRead = spreadMax;
var offset = 0;
var formerSlice = 0;
while (numSlicesToRead > 0)
{
var data = dataInBuffer.Array[i];
var select = selectBuffer.Array[i];
var blockSize = Math.Min(StreamUtils.BUFFER_SIZE, numSlicesToRead);
dataReader.Read(dataInBuffer, 0, blockSize);
selectReader.Read(selectBuffer, 0, blockSize);

// This loop replicates the input data on the output select times
for (int j = 0; j < select; j++)
// This loop iterates through the input data
for (int i = 0; i < blockSize; i++)
{
// Buffer result data
dataOutBuffer.Array[offset] = data;
sliceBuffer.Array[offset] = formerSlice;
offset++;
var data = dataInBuffer[i];
var select = selectBuffer[i];

// Write data out if buffer is full
if (offset == StreamUtils.BUFFER_SIZE)
// This loop replicates the input data on the output select times
for (int j = 0; j < select; j++)
{
dataWriter.Write(dataOutBuffer.Array, 0, StreamUtils.BUFFER_SIZE);
formerSliceWriter.Write(sliceBuffer.Array, 0, StreamUtils.BUFFER_SIZE);
offset = 0;
// Buffer result data
dataOutBuffer[offset] = data;
sliceBuffer[offset] = formerSlice;
offset++;

// Write data out if buffer is full
if (offset == StreamUtils.BUFFER_SIZE)
{
dataWriter.Write(dataOutBuffer, 0, StreamUtils.BUFFER_SIZE);
formerSliceWriter.Write(sliceBuffer, 0, StreamUtils.BUFFER_SIZE);
offset = 0;
}
}

formerSlice++;
}

formerSlice++;
numSlicesToRead -= blockSize;
}
// Write any buffered output data left
if (offset > 0)
{
dataWriter.Write(dataOutBuffer, 0, offset);
formerSliceWriter.Write(sliceBuffer, 0, offset);
}

numSlicesToRead -= blockSize;
}
// Write any buffered output data left
if (offset > 0)
finally
{
dataWriter.Write(dataOutBuffer.Array, 0, offset);
formerSliceWriter.Write(sliceBuffer.Array, 0, offset);
MemoryPool<T>.PutArray(dataInBuffer);
MemoryPool<T>.PutArray(dataOutBuffer);
MemoryPool<int>.PutArray(selectBuffer);
MemoryPool<int>.PutArray(sliceBuffer);
}
}
}
Expand Down

0 comments on commit 54744cc

Please sign in to comment.