Pipeline performance tweaks (follow-up) (#37065)
authorNicolas Portmann <ndportmann@gmail.com>
Sun, 11 Oct 2020 01:39:37 +0000 (03:39 +0200)
committerGitHub <noreply@github.com>
Sun, 11 Oct 2020 01:39:37 +0000 (18:39 -0700)
src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs
src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeWriter.cs

index 5637dd9..90964cd 100644 (file)
@@ -2,7 +2,6 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Buffers;
-using System.Collections.Generic;
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
 using System.Threading;
@@ -112,7 +111,7 @@ namespace System.IO.Pipelines
             // If we're using the default pool then mark it as null since we're just going to use the
             // array pool under the covers
             _pool = options.Pool == MemoryPool<byte>.Shared ? null : options.Pool;
-            _maxPooledBufferSize = _pool?.MaxBufferSize ?? 0;
+            _maxPooledBufferSize = _pool?.MaxBufferSize ?? -1;
             _minimumSegmentSize = options.MinimumSegmentSize;
             _pauseWriterThreshold = options.PauseWriterThreshold;
             _resumeWriterThreshold = options.ResumeWriterThreshold;
@@ -223,13 +222,14 @@ namespace System.IO.Pipelines
 
         private BufferSegment AllocateSegment(int sizeHint)
         {
+            Debug.Assert(sizeHint >= 0);
             BufferSegment newSegment = CreateSegmentUnsynchronized();
 
             int maxSize = _maxPooledBufferSize;
-            if (_pool != null && sizeHint <= maxSize)
+            if (sizeHint <= maxSize)
             {
-                // Use the specified pool as it fits
-                newSegment.SetOwnedMemory(_pool.Rent(GetSegmentSize(sizeHint, maxSize)));
+                // Use the specified pool as it fits. Specified pool is not null as maxSize == -1 if _pool is null.
+                newSegment.SetOwnedMemory(_pool!.Rent(GetSegmentSize(sizeHint, maxSize)));
             }
             else
             {
index 0588b1c..d842293 100644 (file)
@@ -22,6 +22,7 @@ namespace System.IO.Pipelines
         private int _bytesBuffered;
 
         private readonly MemoryPool<byte>? _pool;
+        private readonly int _maxPooledBufferSize;
 
         private CancellationTokenSource? _internalTokenSource;
         private bool _isCompleted;
@@ -56,6 +57,7 @@ namespace System.IO.Pipelines
 
             _minimumBufferSize = options.MinimumBufferSize;
             _pool = options.Pool == MemoryPool<byte>.Shared ? null : options.Pool;
+            _maxPooledBufferSize = _pool?.MaxBufferSize ?? -1;
             _bufferSegmentPool = new BufferSegmentStack(InitialSegmentPoolSize);
             _leaveOpen = options.LeaveOpen;
         }
@@ -149,18 +151,20 @@ namespace System.IO.Pipelines
 
         private BufferSegment AllocateSegment(int sizeHint)
         {
+            Debug.Assert(sizeHint >= 0);
             BufferSegment newSegment = CreateSegmentUnsynchronized();
 
-            if (_pool is null || sizeHint > _pool.MaxBufferSize)
+            int maxSize = _maxPooledBufferSize;
+            if (sizeHint <= maxSize)
             {
-                // Use the array pool
-                int sizeToRequest = GetSegmentSize(sizeHint);
-                newSegment.SetOwnedMemory(ArrayPool<byte>.Shared.Rent(sizeToRequest));
+                // Use the specified pool as it fits. Specified pool is not null as maxSize == -1 if _pool is null.
+                newSegment.SetOwnedMemory(_pool!.Rent(GetSegmentSize(sizeHint, maxSize)));
             }
             else
             {
-                // Use the specified pool as it fits
-                newSegment.SetOwnedMemory(_pool.Rent(GetSegmentSize(sizeHint, _pool.MaxBufferSize)));
+                // Use the array pool
+                int sizeToRequest = GetSegmentSize(sizeHint);
+                newSegment.SetOwnedMemory(ArrayPool<byte>.Shared.Rent(sizeToRequest));
             }
 
             _tailMemory = newSegment.AvailableMemory;