-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory<byte> buffer field backing MemoryStream #84103
Conversation
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsPrototype of a Memory buffer field backing MemoryStream. Benchmarks results: BenchmarkDotNet=v0.13.2.2052-nightly, OS=Windows 11 (10.0.22621.1413)
Intel Core i7-8700 CPU 3.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET SDK=8.0.100-preview.3.23173.11
[Host] : .NET 8.0.0 (8.0.23.17002), X64 RyuJIT AVX2
Job-FXZMRD : .NET 8.0.0 (42.42.42.42424), X64 RyuJIT AVX2
Job-GSUBOA : .NET 8.0.0 (42.42.42.42424), X64 RyuJIT AVX2
PowerPlanMode=00000000-0000-0000-0000-000000000000 IterationTime=250.0000 ms MaxIterationCount=20
MinIterationCount=15 WarmupCount=1
Theere are regressions on Span-based methods when the buffer is 64 or 1024 bytes. + _buffer.Span.Slice(_position, n).CopyTo(buffer);
- new Span<byte>(_buffer, _position, n).CopyTo(buffer); In this sharplab.io sample you can see that copying from Memory to Span this way requires more assembly, 42 vs 71 instructions. One possible way to solve the regressions is by pinning the Memory for the duration of the MemoryStream. That's my next step here, will report back with the results.
|
Could enable #22838.
Introducing the Memory field slows-down small buffer scenarios (1, 100) this is because of the increased code complexity. However, the regression diminishes on large buffer ones (10k, and above).
Benchmarks results:
One possible way to solve the regressions is by pinning the Memory for the duration of the MemoryStream. That's my next step here, will report back with the results.EDIT: Pinning heavily impacts the MemoryStream ctor (30x slower) and as @stephentoub pointed out to me, it is dangerous as someone may unpin the buffer when the memorystream is in use or they may forget to call dispose.