Skip to content
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

Closed
wants to merge 3 commits into from

Conversation

jozkee
Copy link
Member

@jozkee jozkee commented Mar 29, 2023

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:

BenchmarkDotNet=v0.13.2.2052-nightly, OS=Windows 10 (10.0.19045.2788)
AMD Ryzen 9 5900X, 1 CPU, 24 logical and 12 physical cores
.NET SDK=8.0.100-preview.3.23178.7
  [Host]     : .NET 8.0.0 (8.0.23.17408), X64 RyuJIT AVX2
  Job-GVZZUP : .NET 8.0.0 (42.42.42.42424), X64 RyuJIT AVX2
  Job-IRKZSL : .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  
Method Job BufferSize Ratio
ReadByte baseline 1 1.00
ReadByte feature 1 1.12
ReadByteArray baseline 1 1.00
ReadByteArray feature 1 1.17
ReadSpan baseline 1 1.00
ReadSpan feature 1 1.15
WriteByte baseline 1 1.00
WriteByte feature 1 1.19
WriteByteArray baseline 1 1.00
WriteByteArray feature 1 1.26
WriteSpan baseline 1 1.00
WriteSpan feature 1 1.17
CopyTo baseline 1 1.00
CopyTo feature 1 1.23
ReadByte baseline 100 1.00
ReadByte feature 100 1.28
ReadByteArray baseline 100 1.00
ReadByteArray feature 100 1.05
ReadSpan baseline 100 1.00
ReadSpan feature 100 1.14
WriteByte baseline 100 1.00
WriteByte feature 100 1.01
WriteByteArray baseline 100 1.00
WriteByteArray feature 100 1.11
WriteSpan baseline 100 1.00
WriteSpan feature 100 1.18
CopyTo baseline 100 1.00
CopyTo feature 100 1.19
ReadByte baseline 100000 1.00
ReadByte feature 100000 1.17
ReadByteArray baseline 100000 1.00
ReadByteArray feature 100000 1.00
ReadSpan baseline 100000 1.00
ReadSpan feature 100000 1.03
WriteByte baseline 100000 1.00
WriteByte feature 100000 1.03
WriteByteArray baseline 100000 1.00
WriteByteArray feature 100000 1.01
WriteSpan baseline 100000 1.00
WriteSpan feature 100000 1.01
CopyTo baseline 100000 1.00
CopyTo feature 100000 1.03
ReadByte baseline 100000000 1.00
ReadByte feature 100000000 1.30
ReadByteArray baseline 100000000 1.00
ReadByteArray feature 100000000 1.00
ReadSpan baseline 100000000 1.00
ReadSpan feature 100000000 0.99
WriteByte baseline 100000000 1.00
WriteByte feature 100000000 1.04
WriteByteArray baseline 100000000 1.00
WriteByteArray feature 100000000 0.99
WriteSpan baseline 100000000 1.00
WriteSpan feature 100000000 1.00
CopyTo baseline 100000000 1.00
CopyTo feature 100000000 1.01
ReadAsyncByteArray baseline 1 1.00
ReadAsyncByteArray feature 1 1.03
ReadAsyncMemory baseline 1 1.00
ReadAsyncMemory feature 1 1.06
WriteAsyncByteArray baseline 1 1.00
WriteAsyncByteArray feature 1 1.08
WriteAsyncMemory baseline 1 1.00
WriteAsyncMemory feature 1 1.02
CopyToAsync baseline 1 1.00
CopyToAsync feature 1 1.18
ReadAsyncByteArray baseline 100 1.00
ReadAsyncByteArray feature 100 1.06
ReadAsyncMemory baseline 100 1.00
ReadAsyncMemory feature 100 1.11
WriteAsyncByteArray baseline 100 1.00
WriteAsyncByteArray feature 100 1.05
WriteAsyncMemory baseline 100 1.00
WriteAsyncMemory feature 100 0.98
CopyToAsync baseline 100 1.00
CopyToAsync feature 100 1.10
ReadAsyncByteArray baseline 100000 1.00
ReadAsyncByteArray feature 100000 0.96
ReadAsyncMemory baseline 100000 1.00
ReadAsyncMemory feature 100000 0.97
WriteAsyncByteArray baseline 100000 1.00
WriteAsyncByteArray feature 100000 0.99
WriteAsyncMemory baseline 100000 1.00
WriteAsyncMemory feature 100000 1.02
CopyToAsync baseline 100000 1.00
CopyToAsync feature 100000 0.96
ReadAsyncByteArray baseline 100000000 1.00
ReadAsyncByteArray feature 100000000 1.00
ReadAsyncMemory baseline 100000000 1.00
ReadAsyncMemory feature 100000000 1.00
WriteAsyncByteArray baseline 100000000 1.00
WriteAsyncByteArray feature 100000000 1.00
WriteAsyncMemory baseline 100000000 1.00
WriteAsyncMemory feature 100000000 1.00
CopyToAsync baseline 100000000 1.00
CopyToAsync feature 100000000 1.03

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.

@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

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.

@ghost
Copy link

ghost commented Mar 29, 2023

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

Issue Details

Prototype 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  
Method Job Toolchain UseMemoryCtor BufferSize Mean Error StdDev Median Min Max Ratio RatioSD Gen0 Gen1 Allocated Alloc Ratio
ReadByteArray Job-FXZMRD main False 64 24.76 ns 0.528 ns 0.586 ns 24.79 ns 23.66 ns 25.76 ns 1.00 0.00 0.0102 - 64 B 1.00
ReadByteArray Job-GSUBOA feature False 64 25.49 ns 0.537 ns 0.502 ns 25.23 ns 24.93 ns 26.34 ns 1.03 0.03 0.0127 - 80 B 1.25
ReadSpan Job-FXZMRD main False 64 19.60 ns 0.322 ns 0.285 ns 19.62 ns 19.14 ns 20.08 ns 1.00 0.00 0.0102 - 64 B 1.00
ReadSpan Job-GSUBOA feature False 64 25.51 ns 0.422 ns 0.395 ns 25.39 ns 24.94 ns 26.29 ns 1.30 0.02 0.0127 - 80 B 1.25
WriteByteArray Job-FXZMRD main False 64 22.26 ns 0.240 ns 0.213 ns 22.27 ns 21.82 ns 22.67 ns 1.00 0.00 0.0102 - 64 B 1.00
WriteByteArray Job-GSUBOA feature False 64 22.86 ns 0.384 ns 0.360 ns 22.82 ns 22.37 ns 23.63 ns 1.03 0.02 0.0127 - 80 B 1.25
WriteSpan Job-FXZMRD main False 64 18.38 ns 0.295 ns 0.276 ns 18.47 ns 17.95 ns 19.01 ns 1.00 0.00 0.0101 - 64 B 1.00
WriteSpan Job-GSUBOA feature False 64 21.71 ns 0.238 ns 0.222 ns 21.68 ns 21.46 ns 22.22 ns 1.18 0.01 0.0127 - 80 B 1.25
CopyTo Job-FXZMRD main False 64 54.69 ns 0.590 ns 0.552 ns 54.54 ns 53.92 ns 55.62 ns 1.00 0.00 0.0649 - 408 B 1.00
CopyTo Job-GSUBOA feature False 64 60.73 ns 0.895 ns 0.837 ns 60.67 ns 58.96 ns 62.22 ns 1.11 0.01 0.0699 - 440 B 1.08
ReadByteArray Job-FXZMRD main False 1024 31.45 ns 0.256 ns 0.240 ns 31.38 ns 31.17 ns 31.94 ns 1.00 0.00 0.0102 - 64 B 1.00
ReadByteArray Job-GSUBOA feature False 1024 35.04 ns 0.386 ns 0.361 ns 35.03 ns 34.42 ns 35.62 ns 1.11 0.01 0.0127 - 80 B 1.25
ReadSpan Job-FXZMRD main False 1024 26.96 ns 0.333 ns 0.311 ns 26.87 ns 26.59 ns 27.47 ns 1.00 0.00 0.0101 - 64 B 1.00
ReadSpan Job-GSUBOA feature False 1024 32.48 ns 0.433 ns 0.405 ns 32.53 ns 31.80 ns 33.08 ns 1.20 0.02 0.0126 - 80 B 1.25
WriteByteArray Job-FXZMRD main False 1024 29.25 ns 0.440 ns 0.412 ns 29.12 ns 28.78 ns 30.22 ns 1.00 0.00 0.0101 - 64 B 1.00
WriteByteArray Job-GSUBOA feature False 1024 30.17 ns 0.440 ns 0.411 ns 30.08 ns 29.47 ns 30.93 ns 1.03 0.02 0.0127 - 80 B 1.25
WriteSpan Job-FXZMRD main False 1024 25.91 ns 0.359 ns 0.336 ns 25.86 ns 25.45 ns 26.71 ns 1.00 0.00 0.0102 - 64 B 1.00
WriteSpan Job-GSUBOA feature False 1024 27.46 ns 0.333 ns 0.312 ns 27.53 ns 26.76 ns 27.87 ns 1.06 0.02 0.0127 - 80 B 1.25
CopyTo Job-FXZMRD main False 1024 90.64 ns 1.383 ns 1.226 ns 90.81 ns 88.95 ns 92.52 ns 1.00 0.00 0.1872 - 1176 B 1.00
CopyTo Job-GSUBOA feature False 1024 98.92 ns 1.266 ns 1.122 ns 98.76 ns 97.05 ns 101.20 ns 1.09 0.01 0.1924 0.0008 1208 B 1.03
ReadByteArray Job-FXZMRD main False 10000 146.38 ns 1.866 ns 1.746 ns 146.20 ns 144.21 ns 150.07 ns 1.00 0.00 0.0099 - 64 B 1.00
ReadByteArray Job-GSUBOA feature False 10000 151.54 ns 1.496 ns 1.399 ns 151.95 ns 149.24 ns 154.02 ns 1.04 0.02 0.0124 - 80 B 1.25
ReadSpan Job-FXZMRD main False 10000 140.47 ns 1.291 ns 1.008 ns 140.46 ns 138.80 ns 142.44 ns 1.00 0.00 0.0102 - 64 B 1.00
ReadSpan Job-GSUBOA feature False 10000 151.43 ns 2.828 ns 2.645 ns 151.11 ns 148.00 ns 157.23 ns 1.08 0.02 0.0126 - 80 B 1.25
WriteByteArray Job-FXZMRD main False 10000 143.47 ns 1.552 ns 1.451 ns 143.10 ns 141.70 ns 147.03 ns 1.00 0.00 0.0097 - 64 B 1.00
WriteByteArray Job-GSUBOA feature False 10000 111.38 ns 2.194 ns 2.253 ns 111.22 ns 108.24 ns 115.95 ns 0.77 0.02 0.0123 - 80 B 1.25
WriteSpan Job-FXZMRD main False 10000 103.88 ns 1.666 ns 1.558 ns 103.62 ns 102.09 ns 107.06 ns 1.00 0.00 0.0100 - 64 B 1.00
WriteSpan Job-GSUBOA feature False 10000 145.23 ns 1.514 ns 1.417 ns 145.22 ns 143.66 ns 148.26 ns 1.40 0.03 0.0122 - 80 B 1.25
CopyTo Job-FXZMRD main False 10000 549.80 ns 6.576 ns 5.829 ns 549.06 ns 536.40 ns 557.83 ns 1.00 0.00 1.6167 0.0592 10152 B 1.00
CopyTo Job-GSUBOA feature False 10000 558.25 ns 6.200 ns 5.496 ns 558.95 ns 549.64 ns 567.89 ns 1.02 0.01 1.6223 - 10184 B 1.00
ReadByteArray Job-FXZMRD main False 64000 1,109.03 ns 21.272 ns 21.845 ns 1,107.96 ns 1,074.60 ns 1,139.98 ns 1.00 0.00 0.0087 - 64 B 1.00
ReadByteArray Job-GSUBOA feature False 64000 1,356.73 ns 9.454 ns 7.895 ns 1,359.95 ns 1,340.21 ns 1,365.47 ns 1.23 0.02 0.0109 - 80 B 1.25
ReadSpan Job-FXZMRD main False 64000 1,357.41 ns 8.072 ns 7.155 ns 1,357.86 ns 1,344.91 ns 1,370.49 ns 1.00 0.00 0.0054 - 64 B 1.00
ReadSpan Job-GSUBOA feature False 64000 1,099.13 ns 15.933 ns 14.125 ns 1,094.31 ns 1,082.48 ns 1,127.61 ns 0.81 0.01 0.0086 - 80 B 1.25
WriteByteArray Job-FXZMRD main False 64000 1,296.77 ns 12.269 ns 11.476 ns 1,293.78 ns 1,277.05 ns 1,316.37 ns 1.00 0.00 0.0052 - 64 B 1.00
WriteByteArray Job-GSUBOA feature False 64000 1,060.76 ns 8.416 ns 7.460 ns 1,060.36 ns 1,044.40 ns 1,072.07 ns 0.82 0.01 0.0086 - 80 B 1.25
WriteSpan Job-FXZMRD main False 64000 1,260.64 ns 14.588 ns 13.645 ns 1,261.04 ns 1,236.50 ns 1,281.72 ns 1.00 0.00 0.0102 - 64 B 1.00
WriteSpan Job-GSUBOA feature False 64000 1,299.41 ns 10.985 ns 9.738 ns 1,296.28 ns 1,286.15 ns 1,322.87 ns 1.03 0.01 0.0103 - 80 B 1.25
CopyTo Job-FXZMRD main False 64000 3,390.72 ns 60.050 ns 56.171 ns 3,384.59 ns 3,300.76 ns 3,480.62 ns 1.00 0.00 10.1935 1.4484 64152 B 1.00
CopyTo Job-GSUBOA feature False 64000 3,396.88 ns 66.256 ns 73.644 ns 3,395.08 ns 3,240.92 ns 3,552.30 ns 1.00 0.03 10.1991 1.4532 64184 B 1.00
ReadByteArray Job-FXZMRD main True 64 NA NA NA NA NA NA ? ? - - - ?
ReadByteArray Job-GSUBOA feature True 64 24.03 ns 0.438 ns 0.388 ns 23.86 ns 23.48 ns 24.99 ns ? ? 0.0127 - 80 B ?
ReadSpan Job-FXZMRD main True 64 NA NA NA NA NA NA ? ? - - - ?
ReadSpan Job-GSUBOA feature True 64 23.04 ns 0.189 ns 0.158 ns 23.06 ns 22.81 ns 23.41 ns ? ? 0.0127 - 80 B ?
WriteByteArray Job-FXZMRD main True 64 NA NA NA NA NA NA ? ? - - - ?
WriteByteArray Job-GSUBOA feature True 64 21.47 ns 0.286 ns 0.267 ns 21.38 ns 20.93 ns 21.87 ns ? ? 0.0127 - 80 B ?
WriteSpan Job-FXZMRD main True 64 NA NA NA NA NA NA ? ? - - - ?
WriteSpan Job-GSUBOA feature True 64 20.45 ns 0.293 ns 0.275 ns 20.40 ns 20.11 ns 20.98 ns ? ? 0.0127 - 80 B ?
CopyTo Job-FXZMRD main True 64 NA NA NA NA NA NA ? ? - - - ?
CopyTo Job-GSUBOA feature True 64 64.02 ns 1.679 ns 1.934 ns 64.44 ns 61.11 ns 67.50 ns ? ? 0.0699 - 440 B ?
ReadByteArray Job-FXZMRD main True 1024 NA NA NA NA NA NA ? ? - - - ?
ReadByteArray Job-GSUBOA feature True 1024 34.03 ns 0.548 ns 0.512 ns 33.91 ns 33.14 ns 34.96 ns ? ? 0.0126 - 80 B ?
ReadSpan Job-FXZMRD main True 1024 NA NA NA NA NA NA ? ? - - - ?
ReadSpan Job-GSUBOA feature True 1024 34.16 ns 0.335 ns 0.314 ns 34.07 ns 33.76 ns 34.75 ns ? ? 0.0127 - 80 B ?
WriteByteArray Job-FXZMRD main True 1024 NA NA NA NA NA NA ? ? - - - ?
WriteByteArray Job-GSUBOA feature True 1024 28.57 ns 0.379 ns 0.354 ns 28.43 ns 28.14 ns 29.48 ns ? ? 0.0127 - 80 B ?
WriteSpan Job-FXZMRD main True 1024 NA NA NA NA NA NA ? ? - - - ?
WriteSpan Job-GSUBOA feature True 1024 26.70 ns 0.372 ns 0.348 ns 26.82 ns 26.12 ns 27.19 ns ? ? 0.0127 - 80 B ?
CopyTo Job-FXZMRD main True 1024 NA NA NA NA NA NA ? ? - - - ?
CopyTo Job-GSUBOA feature True 1024 98.77 ns 1.319 ns 1.234 ns 99.22 ns 96.40 ns 100.52 ns ? ? 0.1925 0.0008 1208 B ?
ReadByteArray Job-FXZMRD main True 10000 NA NA NA NA NA NA ? ? - - - ?
ReadByteArray Job-GSUBOA feature True 10000 145.69 ns 2.821 ns 2.771 ns 145.93 ns 141.46 ns 150.84 ns ? ? 0.0124 - 80 B ?
ReadSpan Job-FXZMRD main True 10000 NA NA NA NA NA NA ? ? - - - ?
ReadSpan Job-GSUBOA feature True 10000 149.14 ns 1.622 ns 1.517 ns 148.74 ns 147.27 ns 151.60 ns ? ? 0.0125 - 80 B ?
WriteByteArray Job-FXZMRD main True 10000 NA NA NA NA NA NA ? ? - - - ?
WriteByteArray Job-GSUBOA feature True 10000 107.82 ns 1.443 ns 1.350 ns 108.21 ns 105.59 ns 109.76 ns ? ? 0.0126 - 80 B ?
WriteSpan Job-FXZMRD main True 10000 NA NA NA NA NA NA ? ? - - - ?
WriteSpan Job-GSUBOA feature True 10000 147.79 ns 1.336 ns 1.185 ns 147.47 ns 145.98 ns 150.35 ns ? ? 0.0127 - 80 B ?
CopyTo Job-FXZMRD main True 10000 NA NA NA NA NA NA ? ? - - - ?
CopyTo Job-GSUBOA feature True 10000 552.61 ns 10.174 ns 9.019 ns 551.07 ns 539.32 ns 572.80 ns ? ? 1.6228 - 10184 B ?
ReadByteArray Job-FXZMRD main True 64000 NA NA NA NA NA NA ? ? - - - ?
ReadByteArray Job-GSUBOA feature True 64000 1,347.30 ns 16.865 ns 14.083 ns 1,351.55 ns 1,317.65 ns 1,363.90 ns ? ? 0.0107 - 80 B ?
ReadSpan Job-FXZMRD main True 64000 NA NA NA NA NA NA ? ? - - - ?
ReadSpan Job-GSUBOA feature True 64000 1,092.07 ns 12.388 ns 11.588 ns 1,091.34 ns 1,072.76 ns 1,115.02 ns ? ? 0.0088 - 80 B ?
WriteByteArray Job-FXZMRD main True 64000 NA NA NA NA NA NA ? ? - - - ?
WriteByteArray Job-GSUBOA feature True 64000 1,058.39 ns 13.575 ns 12.034 ns 1,058.17 ns 1,040.97 ns 1,079.90 ns ? ? 0.0126 - 80 B ?
WriteSpan Job-FXZMRD main True 64000 NA NA NA NA NA NA ? ? - - - ?
WriteSpan Job-GSUBOA feature True 64000 1,309.67 ns 23.591 ns 22.067 ns 1,311.32 ns 1,275.12 ns 1,356.82 ns ? ? 0.0103 - 80 B ?
CopyTo Job-FXZMRD main True 64000 NA NA NA NA NA NA ? ? - - - ?
CopyTo Job-GSUBOA feature True 64000 3,433.90 ns 39.218 ns 34.766 ns 3,440.18 ns 3,365.72 ns 3,483.48 ns ? ? 10.1973 1.4492 64184 B ?
ReadAsyncByteArray Job-FXZMRD main False 64 51.94 ns 0.847 ns 0.792 ns 52.14 ns 50.54 ns 53.15 ns 1.00 0.00 0.0216 - 136 B 1.00
ReadAsyncByteArray Job-GSUBOA feature False 64 52.43 ns 0.721 ns 0.675 ns 52.26 ns 51.53 ns 53.77 ns 1.01 0.02 0.0240 - 152 B 1.12
ReadAsyncMemory Job-FXZMRD main False 64 63.78 ns 0.928 ns 0.868 ns 63.79 ns 62.37 ns 65.72 ns 1.00 0.00 0.0100 - 64 B 1.00
ReadAsyncMemory Job-GSUBOA feature False 64 64.76 ns 0.955 ns 0.893 ns 64.75 ns 63.48 ns 66.96 ns 1.02 0.02 0.0126 - 80 B 1.25
WriteAsyncByteArray Job-FXZMRD main False 64 35.87 ns 0.564 ns 0.528 ns 36.04 ns 35.13 ns 36.76 ns 1.00 0.00 0.0101 - 64 B 1.00
WriteAsyncByteArray Job-GSUBOA feature False 64 38.00 ns 0.384 ns 0.320 ns 37.94 ns 37.57 ns 38.80 ns 1.06 0.01 0.0127 - 80 B 1.25
WriteAsyncMemory Job-FXZMRD main False 64 43.26 ns 0.441 ns 0.412 ns 43.25 ns 42.49 ns 43.91 ns 1.00 0.00 0.0101 - 64 B 1.00
WriteAsyncMemory Job-GSUBOA feature False 64 44.85 ns 0.345 ns 0.306 ns 44.83 ns 44.42 ns 45.31 ns 1.04 0.01 0.0127 - 80 B 1.25
CopyToAsync Job-FXZMRD main False 64 84.32 ns 1.127 ns 0.999 ns 84.12 ns 83.08 ns 86.81 ns 1.00 0.00 0.0649 - 408 B 1.00
CopyToAsync Job-GSUBOA feature False 64 94.82 ns 1.538 ns 1.439 ns 94.49 ns 93.06 ns 97.99 ns 1.12 0.02 0.0700 - 440 B 1.08
ReadAsyncByteArray Job-FXZMRD main False 1024 60.33 ns 0.766 ns 0.640 ns 60.39 ns 59.43 ns 61.25 ns 1.00 0.00 0.0216 - 136 B 1.00
ReadAsyncByteArray Job-GSUBOA feature False 1024 60.69 ns 0.963 ns 0.900 ns 60.67 ns 59.43 ns 62.28 ns 1.01 0.02 0.0241 - 152 B 1.12
ReadAsyncMemory Job-FXZMRD main False 1024 69.93 ns 0.700 ns 0.655 ns 69.83 ns 68.89 ns 70.75 ns 1.00 0.00 0.0101 - 64 B 1.00
ReadAsyncMemory Job-GSUBOA feature False 1024 75.28 ns 0.661 ns 0.618 ns 75.41 ns 74.47 ns 76.36 ns 1.08 0.01 0.0127 - 80 B 1.25
WriteAsyncByteArray Job-FXZMRD main False 1024 43.56 ns 0.516 ns 0.458 ns 43.60 ns 42.98 ns 44.65 ns 1.00 0.00 0.0100 - 64 B 1.00
WriteAsyncByteArray Job-GSUBOA feature False 1024 43.66 ns 0.787 ns 0.736 ns 43.46 ns 42.77 ns 45.03 ns 1.00 0.02 0.0126 - 80 B 1.25
WriteAsyncMemory Job-FXZMRD main False 1024 52.31 ns 0.900 ns 0.842 ns 51.97 ns 51.15 ns 53.86 ns 1.00 0.00 0.0101 - 64 B 1.00
WriteAsyncMemory Job-GSUBOA feature False 1024 51.64 ns 0.681 ns 0.637 ns 51.75 ns 50.76 ns 52.86 ns 0.99 0.02 0.0127 - 80 B 1.25
CopyToAsync Job-FXZMRD main False 1024 119.44 ns 1.861 ns 1.741 ns 118.92 ns 117.17 ns 123.00 ns 1.00 0.00 0.1874 - 1176 B 1.00
CopyToAsync Job-GSUBOA feature False 1024 132.04 ns 2.025 ns 1.691 ns 131.76 ns 129.14 ns 134.12 ns 1.10 0.02 0.1921 0.0005 1208 B 1.03
ReadAsyncByteArray Job-FXZMRD main False 10000 175.07 ns 1.626 ns 1.521 ns 174.59 ns 172.98 ns 177.92 ns 1.00 0.00 0.0215 - 136 B 1.00
ReadAsyncByteArray Job-GSUBOA feature False 10000 140.37 ns 1.800 ns 1.684 ns 139.96 ns 138.45 ns 143.89 ns 0.80 0.01 0.0241 - 152 B 1.12
ReadAsyncMemory Job-FXZMRD main False 10000 192.67 ns 1.990 ns 1.862 ns 192.96 ns 189.36 ns 195.48 ns 1.00 0.00 0.0098 - 64 B 1.00
ReadAsyncMemory Job-GSUBOA feature False 10000 152.92 ns 1.964 ns 1.837 ns 152.25 ns 150.87 ns 156.42 ns 0.79 0.01 0.0128 - 80 B 1.25
WriteAsyncByteArray Job-FXZMRD main False 10000 163.39 ns 2.018 ns 1.887 ns 163.36 ns 159.94 ns 166.93 ns 1.00 0.00 0.0099 - 64 B 1.00
WriteAsyncByteArray Job-GSUBOA feature False 10000 127.44 ns 2.576 ns 2.410 ns 126.67 ns 124.54 ns 132.09 ns 0.78 0.02 0.0127 - 80 B 1.25
WriteAsyncMemory Job-FXZMRD main False 10000 139.06 ns 2.766 ns 2.717 ns 139.50 ns 133.93 ns 143.69 ns 1.00 0.00 0.0098 - 64 B 1.00
WriteAsyncMemory Job-GSUBOA feature False 10000 169.10 ns 1.478 ns 1.382 ns 169.23 ns 166.96 ns 171.60 ns 1.22 0.03 0.0126 - 80 B 1.25
CopyToAsync Job-FXZMRD main False 10000 635.22 ns 27.372 ns 31.521 ns 650.53 ns 591.66 ns 671.64 ns 1.00 0.00 1.6163 0.0576 10152 B 1.00
CopyToAsync Job-GSUBOA feature False 10000 611.03 ns 9.918 ns 9.277 ns 609.48 ns 596.48 ns 625.30 ns 0.98 0.05 1.6211 - 10184 B 1.00
ReadAsyncByteArray Job-FXZMRD main False 64000 1,399.53 ns 24.178 ns 22.616 ns 1,400.04 ns 1,368.39 ns 1,429.89 ns 1.00 0.00 0.0167 - 136 B 1.00
ReadAsyncByteArray Job-GSUBOA feature False 64000 1,387.39 ns 11.986 ns 10.009 ns 1,387.76 ns 1,364.63 ns 1,408.65 ns 0.99 0.02 0.0221 - 152 B 1.12
ReadAsyncMemory Job-FXZMRD main False 64000 1,423.96 ns 16.715 ns 14.818 ns 1,420.90 ns 1,403.35 ns 1,454.74 ns 1.00 0.00 0.0056 - 64 B 1.00
ReadAsyncMemory Job-GSUBOA feature False 64000 1,427.20 ns 18.187 ns 17.012 ns 1,421.71 ns 1,396.99 ns 1,451.42 ns 1.00 0.02 0.0114 - 80 B 1.25
WriteAsyncByteArray Job-FXZMRD main False 64000 1,323.33 ns 14.059 ns 12.463 ns 1,323.98 ns 1,296.55 ns 1,346.59 ns 1.00 0.00 0.0052 - 64 B 1.00
WriteAsyncByteArray Job-GSUBOA feature False 64000 1,283.28 ns 11.726 ns 9.791 ns 1,283.85 ns 1,271.84 ns 1,307.76 ns 0.97 0.01 0.0104 - 80 B 1.25
WriteAsyncMemory Job-FXZMRD main False 64000 1,096.48 ns 11.621 ns 10.870 ns 1,098.36 ns 1,078.84 ns 1,112.47 ns 1.00 0.00 0.0087 - 64 B 1.00
WriteAsyncMemory Job-GSUBOA feature False 64000 1,296.39 ns 12.704 ns 11.262 ns 1,293.48 ns 1,282.77 ns 1,316.65 ns 1.18 0.01 0.0105 - 80 B 1.25
CopyToAsync Job-FXZMRD main False 64000 3,409.89 ns 52.304 ns 48.926 ns 3,421.42 ns 3,316.68 ns 3,462.94 ns 1.00 0.00 10.2004 1.4493 64152 B 1.00
CopyToAsync Job-GSUBOA feature False 64000 3,384.38 ns 66.792 ns 65.598 ns 3,368.37 ns 3,282.08 ns 3,504.56 ns 0.99 0.02 10.1933 1.4522 64184 B 1.00
ReadAsyncByteArray Job-FXZMRD main True 64 NA NA NA NA NA NA ? ? - - - ?
ReadAsyncByteArray Job-GSUBOA feature True 64 51.43 ns 0.349 ns 0.310 ns 51.39 ns 50.84 ns 51.96 ns ? ? 0.0240 - 152 B ?
ReadAsyncMemory Job-FXZMRD main True 64 NA NA NA NA NA NA ? ? - - - ?
ReadAsyncMemory Job-GSUBOA feature True 64 63.18 ns 0.688 ns 0.643 ns 63.27 ns 61.89 ns 64.02 ns ? ? 0.0126 - 80 B ?
WriteAsyncByteArray Job-FXZMRD main True 64 NA NA NA NA NA NA ? ? - - - ?
WriteAsyncByteArray Job-GSUBOA feature True 64 36.13 ns 0.463 ns 0.433 ns 35.95 ns 35.66 ns 36.90 ns ? ? 0.0126 - 80 B ?
WriteAsyncMemory Job-FXZMRD main True 64 NA NA NA NA NA NA ? ? - - - ?
WriteAsyncMemory Job-GSUBOA feature True 64 47.39 ns 0.675 ns 0.632 ns 47.30 ns 46.32 ns 48.57 ns ? ? 0.0126 - 80 B ?
CopyToAsync Job-FXZMRD main True 64 NA NA NA NA NA NA ? ? - - - ?
CopyToAsync Job-GSUBOA feature True 64 89.63 ns 1.099 ns 1.028 ns 89.62 ns 87.62 ns 91.10 ns ? ? 0.0700 - 440 B ?
ReadAsyncByteArray Job-FXZMRD main True 1024 NA NA NA NA NA NA ? ? - - - ?
ReadAsyncByteArray Job-GSUBOA feature True 1024 58.07 ns 0.607 ns 0.538 ns 58.11 ns 57.33 ns 59.08 ns ? ? 0.0241 - 152 B ?
ReadAsyncMemory Job-FXZMRD main True 1024 NA NA NA NA NA NA ? ? - - - ?
ReadAsyncMemory Job-GSUBOA feature True 1024 77.85 ns 1.157 ns 1.082 ns 78.03 ns 76.03 ns 79.44 ns ? ? 0.0126 - 80 B ?
WriteAsyncByteArray Job-FXZMRD main True 1024 NA NA NA NA NA NA ? ? - - - ?
WriteAsyncByteArray Job-GSUBOA feature True 1024 44.91 ns 0.925 ns 0.908 ns 44.68 ns 43.73 ns 46.64 ns ? ? 0.0126 - 80 B ?
WriteAsyncMemory Job-FXZMRD main True 1024 NA NA NA NA NA NA ? ? - - - ?
WriteAsyncMemory Job-GSUBOA feature True 1024 52.48 ns 0.958 ns 0.849 ns 52.41 ns 50.96 ns 54.03 ns ? ? 0.0127 - 80 B ?
CopyToAsync Job-FXZMRD main True 1024 NA NA NA NA NA NA ? ? - - - ?
CopyToAsync Job-GSUBOA feature True 1024 124.32 ns 1.158 ns 1.026 ns 124.60 ns 122.76 ns 125.60 ns ? ? 0.1925 0.0005 1208 B ?
ReadAsyncByteArray Job-FXZMRD main True 10000 NA NA NA NA NA NA ? ? - - - ?
ReadAsyncByteArray Job-GSUBOA feature True 10000 138.25 ns 1.208 ns 1.130 ns 138.01 ns 136.32 ns 140.09 ns ? ? 0.0241 - 152 B ?
ReadAsyncMemory Job-FXZMRD main True 10000 NA NA NA NA NA NA ? ? - - - ?
ReadAsyncMemory Job-GSUBOA feature True 10000 197.85 ns 1.971 ns 1.844 ns 197.01 ns 195.78 ns 201.48 ns ? ? 0.0120 - 80 B ?
WriteAsyncByteArray Job-FXZMRD main True 10000 NA NA NA NA NA NA ? ? - - - ?
WriteAsyncByteArray Job-GSUBOA feature True 10000 163.74 ns 2.018 ns 1.888 ns 163.32 ns 160.96 ns 167.91 ns ? ? 0.0122 - 80 B ?
WriteAsyncMemory Job-FXZMRD main True 10000 NA NA NA NA NA NA ? ? - - - ?
WriteAsyncMemory Job-GSUBOA feature True 10000 168.03 ns 1.321 ns 1.103 ns 167.79 ns 166.10 ns 170.11 ns ? ? 0.0126 - 80 B ?
CopyToAsync Job-FXZMRD main True 10000 NA NA NA NA NA NA ? ? - - - ?
CopyToAsync Job-GSUBOA feature True 10000 602.68 ns 9.944 ns 9.302 ns 602.06 ns 588.83 ns 618.56 ns ? ? 1.6229 - 10184 B ?
ReadAsyncByteArray Job-FXZMRD main True 64000 NA NA NA NA NA NA ? ? - - - ?
ReadAsyncByteArray Job-GSUBOA feature True 64000 1,145.95 ns 12.192 ns 11.404 ns 1,145.05 ns 1,130.43 ns 1,162.21 ns ? ? 0.0228 - 152 B ?
ReadAsyncMemory Job-FXZMRD main True 64000 NA NA NA NA NA NA ? ? - - - ?
ReadAsyncMemory Job-GSUBOA feature True 64000 1,423.85 ns 17.446 ns 16.319 ns 1,424.57 ns 1,386.23 ns 1,448.42 ns ? ? 0.0113 - 80 B ?
WriteAsyncByteArray Job-FXZMRD main True 64000 NA NA NA NA NA NA ? ? - - - ?
WriteAsyncByteArray Job-GSUBOA feature True 64000 1,289.91 ns 14.715 ns 13.765 ns 1,293.48 ns 1,265.44 ns 1,313.55 ns ? ? 0.0103 - 80 B ?
WriteAsyncMemory Job-FXZMRD main True 64000 NA NA NA NA NA NA ? ? - - - ?
WriteAsyncMemory Job-GSUBOA feature True 64000 1,309.82 ns 13.714 ns 12.828 ns 1,306.65 ns 1,287.74 ns 1,339.45 ns ? ? 0.0105 - 80 B ?
CopyToAsync Job-FXZMRD main True 64000 NA NA NA NA NA NA ? ? - - - ?
CopyToAsync Job-GSUBOA feature True 64000 3,417.78 ns 39.073 ns 34.637 ns 3,414.20 ns 3,361.45 ns 3,480.08 ns ? ? 10.1956 1.4506 64184 B ?

Theere are regressions on Span-based methods when the buffer is 64 or 1024 bytes.
e.g: ReadSpan has a 30% regression, I assume is caused by these kind changes:

+ _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.

cc @stephentoub @adamsitnik

Author: Jozkee
Assignees: Jozkee
Labels:

area-System.IO, new-api-needs-documentation

Milestone: -

@jozkee jozkee changed the title Add MemoryStream.ctor(Memory<byte>) Memory<byte> buffer field backing MemoryStream Apr 4, 2023
@jozkee jozkee marked this pull request as ready for review April 4, 2023 14:53
@jozkee jozkee requested a review from stephentoub April 4, 2023 14:54
@ghost ghost locked as resolved and limited conversation to collaborators Jun 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants