-
Notifications
You must be signed in to change notification settings - Fork 193
Use System.Buffers + ValueTask in FormReading #556
Conversation
8ff6275
to
28b6cd9
Compare
Why? The main point of putting it in a new assembly was so it would be usable there: |
28b6cd9
to
25c7ac3
Compare
Entirely my fault as I couldn't follow instructions; when it said it needed |
8d79967
to
88ec9fa
Compare
ValueTask reduces Task allocation by FormReader to 1% which continues to be amortised over time downwards #553 (comment) Revisiting the original allocation issue from 30,000 requests (x10 on original) ValueTask dramatically reduces the Task allocations to around 1% of the current (7MB vs 750MB) |
Nice 👍 |
88ec9fa
to
1db60b9
Compare
Rebased; removed WebEncoders changes as its changed somewhat. |
Sweet 👍 /cc @DavidObando @mnltejaswini |
Love this. |
@@ -43,6 +56,17 @@ public class FileBufferingReadStream : Stream | |||
throw new ArgumentNullException(nameof(tempFileDirectoryAccessor)); | |||
} | |||
|
|||
_bytePool = bytePool; | |||
if (memoryThreshold < 1024 * 1024) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to put this in a constant.
0a5c6b9
to
f270c45
Compare
Rebased, somewhat squashed, feedback changes made |
using (reader) | ||
{ | ||
var pair = await pairTask; | ||
while (pair.HasValue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how does this work? Am I missing something that way over my head?
@rynowak do you mean the splitting of the async
version from the non-async
version (until it becomes async) or the end of read being indicated by a null
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just hadn't read these two lines super well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I imagine a golden time in the future when the compiler automatically does these patterns for you...
@benaadams Can you rebase? |
f270c45
to
ff075e9
Compare
Rebased; note: I had to bump |
}, | ||
"frameworks": { | ||
"net451": { | ||
"frameworkAssemblies": { | ||
"System.Runtime": { "type": "build" } | ||
"System.Runtime": { "type": "build" }, | ||
"System.Threading.Tasks": "4.0.0.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be type build like the other facades
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
// Drain until close received | ||
await ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this ever actually throw?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially, could throw if socket already disconnected or cancellation token cancelled.
This ValueTask pattern causes substantial code duplication and maintenance issues. I don't think it's piratical. Can we split this and just take the buffer pooling? |
The ValueTask does cut the allocations on 30k requests from 750MB to 7MB though /cc @rynowak |
The buffer pooling is ready to merge and unrelated to the ValueTask work. Let's get that merged. We need to come up with a simpler pattern if we're going to use ValueTasks. |
K, will split them later today |
Know what you mean, there are a bunch of higher performance patterns with async that do make the code more confusing as you need to split the code into multiple fragments. I wonder if there is scope to push this into the compiler instead? As it already does that for general async. Would rosyln be the correct repo to raise this? /cc @stephentoub |
|
I recommend we close this pending the roslyn discussion. @benaadams @rynowak? |
That seems fine, I don't think we're going to take this PR in it's current form |
Built on #550
Addressing Task allocations in #553 (last commit in this PR)
ValueTask reduces Task allocation by FormReader to 1%
Post for 30,000 requests - byte[] allocations are as follows 0.5MB on rent vs 440MB on MemoryStream originally
/cc @rynowak @davidfowl @Tratcher @stephentoub