Skip to content
Browse files

Improved performance of Select (Value) node by using arrays directly …

…and removing output slice count by using new DynamicOutputWriter class.
  • Loading branch information...
1 parent 3018178 commit 54744cc76bc5b0b98f58150ef6e90a12da623368 @azeno azeno committed Feb 10, 2014
Showing with 52 additions and 54 deletions.
  1. +52 −54 vvvv45/src/nodes/plugins/_SpreadOperations/SelectNode.cs
View
106 vvvv45/src/nodes/plugins/_SpreadOperations/SelectNode.cs
@@ -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);
}
}
}

0 comments on commit 54744cc

Please sign in to comment.
Something went wrong with that request. Please try again.