Skip to content

Conversation

Trapov
Copy link

@Trapov Trapov commented Dec 7, 2021

No description provided.

@ghost ghost added community-contribution Indicates that the PR has been added by a community member area-System.IO labels Dec 7, 2021
@ghost
Copy link

ghost commented Dec 7, 2021

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

Issue Details

null

Author: Trapov
Assignees: -
Labels:

area-System.IO, community-contribution

Milestone: -

@Trapov
Copy link
Author

Trapov commented Dec 7, 2021

Before:

Method Mean Error StdDev Median Min Max Gen 0 Gen 1 Allocated
ReadLine 695.4 ms 5.83 ms 5.45 ms 695.5 ms 688.4 ms 706.7 ms 179000.0000 - 1 GB
ReadLineAsync 1,138.0 ms 9.84 ms 8.73 ms 1,136.1 ms 1,125.5 ms 1,156.8 ms 294000.0000 1000.0000 2 GB

After:

Method Mean Error StdDev Median Min Max Gen 0 Gen 1 Allocated
ReadLine 685.6 ms 9.11 ms 8.08 ms 684.4 ms 675.9 ms 703.8 ms 179000.0000 - 1 GB
ReadLineAsync 983.7 ms 16.58 ms 14.69 ms 978.8 ms 955.5 ms 1,005.9 ms 294000.0000 1000.0000 2 GB

@Trapov
Copy link
Author

Trapov commented Dec 7, 2021

#62061 <- referenced

@Trapov
Copy link
Author

Trapov commented Dec 7, 2021

Did I broke the CI for arm?

Copy link
Contributor

@deeprobin deeprobin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@deeprobin
Copy link
Contributor

Did I broke the CI for arm?

I think the CI just needs to be restarted, happens often.

/cc @adamsitnik

@Trapov Trapov marked this pull request as ready for review December 7, 2021 19:36
@Trapov Trapov changed the title (DRAFT) Reduce asyncstatemachine cost in readLineAsyncInternal. Reduce asyncstatemachine cost in readLineAsyncInternal. Dec 7, 2021
Copy link
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left some minor style-related comments. Otherwise than that, the changes look good, I am really happy to see the improvements! 👍

I have few more ideas that you could try (in a separate PR):

  • using [AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))] to annotate ReadBufferAsync method (more context: #49903)
  • using vectorized IndexOfAny similarly to what @nietras did in #60463
  • optimizing for happy-path scenario where we know that we don't need to fetch any more data by eliminating awaits

@Trapov big thanks for your contribution!

@adamsitnik adamsitnik added this to the 7.0.0 milestone Dec 8, 2021
i++;
} while (i < tmpCharLen);
i = tmpCharLen - tmpCharPos;
sb ??= new StringBuilder(i + 80);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamsitnik I was wondering whether it would be possible to do pooling of the StringBuilder instance, to avoid this allocation in long line cases?

Copy link
Member

@adamsitnik adamsitnik Dec 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nietras it's definitely a good idea! Perhaps we could even replace the private char array ( _charBuffer) with a StringBuilder, write the chars directly to it and avoid the need of appending? The only thing I am not sure of is what side effects using StringBuilder.ToString(int startIndex, int length) might have

@Trapov
Copy link
Author

Trapov commented Dec 8, 2021

I've left some minor style-related comments. Otherwise than that, the changes look good, I am really happy to see the improvements! 👍

I have few more ideas that you could try (in a separate PR):

@Trapov big thanks for your contribution!

Will open the second PR with those suggestions in mind. Feel free to merge this one, I guess?

@nietras
Copy link
Contributor

nietras commented Dec 8, 2021

@Trapov note that we have a common micro-benchmark for this now with dotnet/performance#2170

FYI: You can compare your changes with main by calling something like:

C:\git\oss\performance\src\benchmarks\micro > dotnet run -c Release -f net6.0 --filter *StreamReaderReadLine* --coreRun "C:\git\oss\runtime-m\artifacts\bin\testhost\net7.0-windows-Release-x64\shared\Microsoft.NETCore.App\7.0.0\CoreRun.exe" "C:\git\oss\runtime-pr\artifacts\bin\testhost\net7.0-windows-Release-x64\shared\Microsoft.NETCore.App\7.0.0\CoreRun.exe"

@Trapov
Copy link
Author

Trapov commented Dec 8, 2021

Before:

Method LineLengthRange Mean Error StdDev Median Min Max Gen 0 Gen 1 Allocated
ReadLine [ 0, 0] 100.46 us 0.571 us 0.476 us 100.55 us 99.56 us 101.02 us 0.3981 - 3 KB
ReadLineAsync [ 0, 0] 533.46 us 6.246 us 4.877 us 531.86 us 527.88 us 546.85 us 187.5000 2.2321 1,155 KB
ReadLine [ 0, 1024] 24.01 us 0.154 us 0.144 us 23.99 us 23.84 us 24.24 us 10.1145 0.0954 62 KB
ReadLineAsync [ 0, 1024] 30.02 us 0.388 us 0.363 us 30.10 us 29.25 us 30.44 us 10.4769 0.1204 65 KB
ReadLine [ 1, 1] 112.55 us 0.670 us 0.594 us 112.40 us 111.75 us 114.04 us 31.7029 - 195 KB
ReadLineAsync [ 1, 1] 331.33 us 6.225 us 5.823 us 331.43 us 322.56 us 344.43 us 125.0000 1.2755 771 KB
ReadLine [ 1, 8] 83.02 us 1.070 us 1.001 us 82.83 us 81.65 us 84.88 us 18.1878 - 112 KB
ReadLineAsync [ 1, 8] 167.10 us 1.645 us 1.539 us 166.82 us 164.92 us 170.07 us 55.7065 0.6793 344 KB
ReadLine [ 9, 32] 37.91 us 0.228 us 0.191 us 37.93 us 37.66 us 38.37 us 9.0799 - 56 KB
ReadLineAsync [ 9, 32] 58.02 us 0.517 us 0.404 us 58.13 us 57.36 us 58.65 us 18.0000 - 110 KB
ReadLine [ 33, 128] 25.94 us 0.124 us 0.103 us 25.96 us 25.76 us 26.08 us 7.2434 - 45 KB
ReadLineAsync [ 33, 128] 35.75 us 0.556 us 0.520 us 35.73 us 34.96 us 36.76 us 9.6047 - 59 KB
ReadLine [ 129, 1024] 23.14 us 0.129 us 0.114 us 23.13 us 22.96 us 23.39 us 10.3390 0.0931 63 KB
ReadLineAsync [ 129, 1024] 29.28 us 0.262 us 0.232 us 29.27 us 28.92 us 29.70 us 10.5716 0.1162 65 KB
ReadLine [1025, 2048] 28.67 us 2.759 us 3.177 us 26.73 us 25.87 us 35.63 us 14.7348 0.2456 91 KB
ReadLineAsync [1025, 2048] 32.10 us 0.555 us 0.492 us 31.96 us 31.51 us 33.18 us 14.8931 0.3819 92 KB

After:

Method LineLengthRange Mean Error StdDev Median Min Max Gen 0 Gen 1 Allocated
ReadLine [ 0, 0] 102.96 us 1.509 us 1.260 us 102.80 us 100.77 us 104.61 us 0.4058 - 3 KB
ReadLineAsync [ 0, 0] 525.29 us 3.205 us 2.841 us 525.50 us 520.59 us 530.45 us 187.5000 2.0833 1,156 KB
ReadLine [ 0, 1024] 23.41 us 0.116 us 0.108 us 23.43 us 23.23 us 23.60 us 10.0897 0.0934 62 KB
ReadLineAsync [ 0, 1024] 20.35 us 0.123 us 0.109 us 20.32 us 20.12 us 20.56 us 10.5110 0.1617 65 KB
ReadLine [ 1, 1] 113.25 us 1.522 us 1.424 us 113.25 us 111.54 us 116.38 us 31.4748 - 195 KB
ReadLineAsync [ 1, 1] 360.37 us 4.846 us 4.047 us 358.64 us 355.89 us 370.21 us 125.0000 1.4205 772 KB
ReadLine [ 1, 8] 84.47 us 0.855 us 0.800 us 84.36 us 83.23 us 85.80 us 18.0556 - 112 KB
ReadLineAsync [ 1, 8] 172.03 us 2.201 us 1.951 us 171.35 us 169.75 us 176.19 us 55.6319 0.6868 344 KB
ReadLine [ 9, 32] 38.08 us 0.267 us 0.250 us 37.94 us 37.66 us 38.46 us 9.0799 - 56 KB
ReadLineAsync [ 9, 32] 56.39 us 0.582 us 0.486 us 56.42 us 55.31 us 57.40 us 17.8257 0.2201 110 KB
ReadLine [ 33, 128] 26.08 us 0.521 us 0.487 us 25.94 us 25.46 us 27.11 us 7.2627 - 45 KB
ReadLineAsync [ 33, 128] 27.65 us 0.213 us 0.178 us 27.71 us 27.37 us 27.87 us 9.6322 0.1095 59 KB
ReadLine [ 129, 1024] 23.15 us 0.172 us 0.161 us 23.10 us 22.92 us 23.45 us 10.2941 0.0919 63 KB
ReadLineAsync [ 129, 1024] 20.28 us 0.193 us 0.171 us 20.25 us 20.07 us 20.58 us 10.5932 0.1630 65 KB
ReadLine [1025, 2048] 24.81 us 0.253 us 0.224 us 24.73 us 24.51 us 25.32 us 14.7638 0.2953 91 KB
ReadLineAsync [1025, 2048] 20.52 us 0.131 us 0.109 us 20.52 us 20.34 us 20.67 us 14.9402 0.4150 92 KB

@Trapov Trapov requested a review from adamsitnik December 8, 2021 10:56
Copy link
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! :shipit:

else
// Note the following common line feed chars:
// \n - UNIX \r\n - DOS \r - Mac
if (ch is '\r' or '\n')
Copy link
Member

@stephentoub stephentoub Dec 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This produces identical IL and asm, doesn't it? I would not expect a perf improvement from this. What will be different and might yield a micro-improvement is ch == '\r' | ch == '\n', removing a (likely-well-predicted) branch.

return null;

return await ConsumeBufferedData().ConfigureAwait(false);
}
Copy link
Member

@stephentoub stephentoub Dec 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this make the NoDataInTheBuffer case more expensive? Does the perf test being run stress this case?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does but it might not be the most used one case, at least that's what I hope for. The benchmarks -> dotnet/performance@529f33c#diff-64fc887dbc1598f2ea871592946f4077593925f80b22cab6f586ea7e1e1b0723


return await ConsumeBufferedData().ConfigureAwait(false);
}
async Task<string?> ConsumeBufferedData()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a theory you can share for why this improves perf? There are three cases here:

  • There's no data in the buffer and we're at EOF.
  • There's no data in the buffer but there's remaining data.
  • There's data in the buffer.

In all three cases, previously you would be calling a single async method. In all three cases, now you're still calling at least one async method, and in the second case, it's now calling a second and doing more work than before. The third case is just adding an extra layer of indirection. And the first case should only occur once per file.

Copy link
Author

@Trapov Trapov Dec 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that I could cut the state-machine in half (and eleminate awaits) and switch in two paths without any state-machines where in one part the third case is making less work and in another part the first/second ones (NoDataInBuffer) are doing more work (but they're not the most used ones probably), at least that was my reasoning behind it. But thinking about it again and looking at the perf-results not every case is a winner. Specificaly short lines are the worst.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method Job Toolchain LineLengthRange Mean Error StdDev Median Min Max Ratio RatioSD Gen 0 Gen 1 Allocated
ReadLineAsync Job-VRCDUV /testhost-main/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 0, 0] 535.71 us 3.930 us 3.281 us 534.51 us 529.92 us 541.75 us 1.00 0.00 187.5000 2.1552 1,155 KB
ReadLineAsync Job-UBMMAT /testhost/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 0, 0] 512.69 us 4.709 us 4.174 us 512.40 us 504.80 us 519.53 us 0.96 0.01 187.5000 2.0161 1,156 KB
ReadLineAsync Job-VRCDUV /testhost-main/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 0, 1024] 29.21 us 0.369 us 0.345 us 29.12 us 28.65 us 29.84 us 1.00 0.00 10.4360 0.1160 65 KB
ReadLineAsync Job-UBMMAT /testhost/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 0, 1024] 19.96 us 0.153 us 0.143 us 19.95 us 19.70 us 20.18 us 0.68 0.01 10.4828 0.1588 65 KB
ReadLineAsync Job-VRCDUV /testhost-main/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 1, 1] 320.86 us 1.957 us 1.634 us 321.01 us 317.07 us 323.00 us 1.00 0.00 125.0000 1.3021 771 KB
ReadLineAsync Job-UBMMAT /testhost/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 1, 1] 322.20 us 1.850 us 1.640 us 322.16 us 319.25 us 325.77 us 1.00 0.01 125.0000 1.2755 772 KB
ReadLineAsync Job-VRCDUV /testhost-main/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 1, 8] 169.12 us 2.478 us 2.069 us 169.55 us 164.25 us 172.48 us 1.00 0.00 55.7796 0.6720 344 KB
ReadLineAsync Job-UBMMAT /testhost/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 1, 8] 172.79 us 2.950 us 2.760 us 172.04 us 168.83 us 177.28 us 1.02 0.02 55.7065 0.6793 344 KB
ReadLineAsync Job-VRCDUV /testhost-main/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 9, 32] 58.74 us 0.469 us 0.391 us 58.80 us 58.05 us 59.53 us 1.00 0.00 17.9228 0.2298 110 KB
ReadLineAsync Job-UBMMAT /testhost/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 9, 32] 56.41 us 0.530 us 0.470 us 56.53 us 55.72 us 57.13 us 0.96 0.01 18.0201 0.2281 110 KB
ReadLineAsync Job-VRCDUV /testhost-main/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 33, 128] 35.15 us 0.317 us 0.281 us 35.13 us 34.73 us 35.60 us 1.00 0.00 9.5291 - 59 KB
ReadLineAsync Job-UBMMAT /testhost/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 33, 128] 27.54 us 0.216 us 0.192 us 27.53 us 27.33 us 27.93 us 0.78 0.01 9.6831 0.1100 59 KB
ReadLineAsync Job-VRCDUV /testhost-main/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 129, 1024] 29.31 us 0.279 us 0.233 us 29.27 us 28.95 us 29.81 us 1.00 0.00 10.5932 0.1177 65 KB
ReadLineAsync Job-UBMMAT /testhost/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [ 129, 1024] 20.26 us 0.105 us 0.088 us 20.29 us 20.05 us 20.34 us 0.69 0.01 10.6041 - 65 KB
ReadLineAsync Job-VRCDUV /testhost-main/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [1025, 2048] 31.22 us 0.457 us 0.405 us 31.31 us 30.56 us 31.99 us 1.00 0.00 14.9457 0.3706 92 KB
ReadLineAsync Job-UBMMAT /testhost/net7.0-OSX-Release-x64/shared/Microsoft.NETCore.App/7.0.0/corerun [1025, 2048] 20.79 us 0.195 us 0.182 us 20.75 us 20.50 us 21.13 us 0.67 0.01 14.9402 0.4150 92 KB

@stephentoub dotnet/performance@529f33c#diff-64fc887dbc1598f2ea871592946f4077593925f80b22cab6f586ea7e1e1b0723

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented out of benchmarks the sync method for cleaner results between main and this branch

@nietras
Copy link
Contributor

nietras commented Dec 8, 2021

@Trapov FYI you can filter benchmarks by adding method name to command line .e.g --filter *StreamReaderReadLine.ReadLineAsync*:

 dotnet run -c Release -f net6.0 --filter *StreamReaderReadLine.ReadLineAsync* --coreRun "C:\git\oss\runtime-m\artifacts\bin\testhost\net7.0-windows-Release-x64\shared\Microsoft.NETCore.App\7.0.0\CoreRun.exe" "C:\git\oss\runtime-pr\artifacts\bin\testhost\net7.0-windows-Release-x64\shared\Microsoft.NETCore.App\7.0.0\CoreRun.exe"

by using this with m and pr you also get ratio column in output that makes it easy to compare relative perf differences.

@Trapov
Copy link
Author

Trapov commented Dec 8, 2021

@Trapov FYI you can filter benchmarks by adding method name to command line .e.g --filter *StreamReaderReadLine.ReadLineAsync*:

 dotnet run -c Release -f net6.0 --filter *StreamReaderReadLine.ReadLineAsync* --coreRun "C:\git\oss\runtime-m\artifacts\bin\testhost\net7.0-windows-Release-x64\shared\Microsoft.NETCore.App\7.0.0\CoreRun.exe" "C:\git\oss\runtime-pr\artifacts\bin\testhost\net7.0-windows-Release-x64\shared\Microsoft.NETCore.App\7.0.0\CoreRun.exe"

by using this with m and pr you also get ratio column in output that makes it easy to compare relative perf differences.

#62479 (comment)

@stephentoub
Copy link
Member

stephentoub commented Dec 8, 2021

Thanks for your efforts here, @Trapov.

I spent some time today looking into this, as I wouldn't have expected this change to make as meaningful a difference as the numbers show: in either case you're still invoking an async method, and the await being removed from one of those async methods isn't even changing the size of that state machine (it's removing an await using an awaiter type that's also used elsewhere in the method), and on top of that the benchmark is using a stream type whose read methods always complete synchronously.

That said, I do see the same results on my machine when I pull down your PR. What's interesting, though, is why the improvement happens. Fundamentally, it looks to be due to the code the C# compiler happens to generate for the exact circumstance in play here. You can see this if you update your commit to just add back the _charPos == _charLen && (await ReadBufferAsync(CancellationToken.None).ConfigureAwait(false)) == 0 check at the beginning of the ConsumeBufferedData method. Even though, due to the guard in ReadLineAsyncInternal, that ReadBufferAsync call will never be hit because _charPos will never be equal to _charLen when we get here, just the presence of that additional await causes a bunch of changes in how the C# compiler is generating the code for this method, e.g. whether it uses a switch or cascading ifs for the jump table, and, at least for me, the previously observed performance difference evaporates. I'm very hestitant to take a change that complicates the code for a win that's likely to be transient.

There are also other improvements possible in ReadLineAsync that will make a much larger impact, like the ones @adamsitnik mentioned earlier. For example, here's a quick hackjob that a) uses IndexOfAny and b) caches a StringBuilder onto StreamReader:
stephentoub@0daab80
With that, I get numbers like the following: here main is what's currently in main, pr is with my cited commit, and pr2 is that commit as well as the change from this PR:

Method Toolchain LineLengthRange Mean Error StdDev Ratio Allocated
ReadLineAsync \main\corerun.exe [ 0, 0] 227.284 us 4.4884 us 4.6093 us 1.00 579 KB
ReadLineAsync \pr2\corerun.exe [ 0, 0] 261.052 us 4.3191 us 3.8288 us 1.15 580 KB
ReadLineAsync \pr\corerun.exe [ 0, 0] 266.604 us 4.9058 us 4.5889 us 1.18 579 KB
ReadLineAsync \main\corerun.exe [ 1, 1] 194.254 us 0.9095 us 0.8062 us 1.00 517 KB
ReadLineAsync \pr2\corerun.exe [ 1, 1] 214.027 us 3.4172 us 3.1964 us 1.10 516 KB
ReadLineAsync \pr\corerun.exe [ 1, 1] 217.440 us 0.7555 us 0.6308 us 1.12 516 KB
ReadLineAsync \main\corerun.exe [ 0, 1024] 23.460 us 0.1394 us 0.1235 us 1.00 64 KB
ReadLineAsync \pr2\corerun.exe [ 0, 1024] 7.523 us 0.0327 us 0.0290 us 0.32 48 KB
ReadLineAsync \pr\corerun.exe [ 0, 1024] 7.342 us 0.0382 us 0.0319 us 0.31 48 KB
ReadLineAsync \main\corerun.exe [ 1, 8] 126.456 us 0.3767 us 0.3146 us 1.00 289 KB
ReadLineAsync \pr2\corerun.exe [ 1, 8] 125.753 us 0.2666 us 0.2082 us 0.99 286 KB
ReadLineAsync \pr\corerun.exe [ 1, 8] 128.383 us 0.5712 us 0.4459 us 1.02 286 KB
ReadLineAsync \main\corerun.exe [ 9, 32] 49.919 us 0.6183 us 0.5784 us 1.00 106 KB
ReadLineAsync \pr2\corerun.exe [ 9, 32] 38.612 us 0.0569 us 0.0504 us 0.77 102 KB
ReadLineAsync \pr\corerun.exe [ 9, 32] 38.819 us 0.5596 us 0.4960 us 0.78 102 KB
ReadLineAsync \main\corerun.exe [ 33, 128] 29.226 us 0.2058 us 0.1825 us 1.00 59 KB
ReadLineAsync \pr2\corerun.exe [ 33, 128] 15.316 us 0.0662 us 0.0552 us 0.52 55 KB
ReadLineAsync \pr\corerun.exe [ 33, 128] 15.215 us 0.0933 us 0.0827 us 0.52 55 KB
ReadLineAsync \main\corerun.exe [ 129, 1024] 23.351 us 0.0945 us 0.0789 us 1.00 63 KB
ReadLineAsync \pr2\corerun.exe [ 129, 1024] 7.196 us 0.0620 us 0.0484 us 0.31 46 KB
ReadLineAsync \pr\corerun.exe [ 129, 1024] 7.355 us 0.0455 us 0.0380 us 0.31 46 KB
ReadLineAsync \main\corerun.exe [1025, 2048] 24.515 us 0.0724 us 0.0642 us 1.00 91 KB
ReadLineAsync \pr2\corerun.exe [1025, 2048] 6.944 us 0.0212 us 0.0177 us 0.28 47 KB
ReadLineAsync \pr\corerun.exe [1025, 2048] 6.816 us 0.0580 us 0.0514 us 0.28 47 KB

This shows much larger wins from main to that commit, and then the improvements seen in this PR largely disappear, I believe because enough was perturbed in the C# codegen to make those transient wins go away.

I'd like to suggest this PR be closed and we instead focus on making some of those other improvements.

@Trapov
Copy link
Author

Trapov commented Dec 8, 2021

Closing this one because of how strongly the changes depend on the compiler and open a new one in a few moments.

@Trapov Trapov closed this Dec 8, 2021
@Trapov Trapov deleted the optimization/net7.0/stream-reader branch December 8, 2021 21:40
@Trapov
Copy link
Author

Trapov commented Dec 8, 2021

#62552

@ghost ghost locked as resolved and limited conversation to collaborators Jan 8, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.IO community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants