-
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
[wasm] Major performance regression serializing and deserializing json #50260
Comments
Tagging subscribers to this area: @eiriktsarpalis, @layomia Issue DetailsFrom 0f64b26...5b77db9 there was a large regression in the aspnetcore blazor json tests. That is a large span of commits because aspnetcore wasn't able to ingest the runtime for an extended period.
|
Tagging subscribers to 'arch-wasm': @lewing Issue DetailsFrom 0f64b26...5b77db9 there was a large regression in the aspnetcore blazor json tests. That is a large span of commits because aspnetcore wasn't able to ingest the runtime for an extended period.
|
There seem to be several changes around text processing in that set. Any thoughts @GrabYourPitchforks |
@lewing I'm not quite sure what tests you're referring to, but check out the below benchmark file. This benchmark exercises specifically the System.Text.Encodings.Web package, separate from System.Text.Json. If you see regressions in this benchmark file, that would be strong evidence that the PR #49373 really is responsible for this. Is it possible to run these benchmarks against the wasm runtime to validate this theory? (You can make the benchmarks run a bit faster by removing the "HTML" and "URL" benchmarks on line 22 of that file.) The logic inside the S.T.E.W project - even for the non-intrinsicified paths - is tuned so that it emits optimized codegen. It's possible that these optimizations benefit the typical codegen scenario but harm wasm. If necessary, we could investigate creating special -wasm.cs versions of these files which contain code patterns better suited for wasm scenarios. Let me know what you think of that idea. |
I should also mention: System.Text.Encodings.Web is not involved with deserialization, only with serialization. If you're seeing regressions in deserialization-only scenarios, that would require pulling in the JSON crew. |
The regression appears to be symmetric so that is a good indication that it is not your change. Someone from @dotnet/aspnet-blazor-eng can probably point to the specific code under test better than I can. |
@lewing do you know what was the smaller regression around March 21st that went away? If it was a fluke, I wonder if the current regression could be as well. |
@steveharter we ran the benchmarks a few times and the regression was consistent. Seems less likely it's transient. |
Yeah, that was one of my first questions too, so we verified. On top of that several more normal benchmark runs have completed and the regression has persisted |
OK.
The property caching mechanism in the serializer attempts to pre-generate some JSON which does call So it is possible #49373 is responsible although since the results are cached by the serializer, it would seem unlikely unless:
|
@lewing can we get a pointer to the benchmark code? That would clear up any confusion and also allow us to determine whether it's following System.Text.Json documented best practice. |
Also re-upping the ping to @dotnet/aspnet-blazor-eng so that we can get a pointer to the code. |
Some quick benchmarking on this reveals that the biggest regressions seem to be in the deserialization. No change in serialization. Deserialization
Serialization
Test repo is https://github.com/captainsafia/TestJsonRegression. The benchmarking code was implemented in |
Thanks @captainsafia for these numbers. I'll leave this pathed in System.Text.Json for now. |
This is caused by |
@pranavkm @captainsafia @lewing If I provided a patch file for dotnet/runtime with a proposed workaround, would you be able to apply the patch, rebuild the wasm-specific System.Private.CoreLib.dll, drop it into your benchmark app, and see if it resolves your perf issue? Keep in mind you'll also want to compare the before/after of the size on disk of a trimmed Blazor app. |
I tested with a console app and reverting that commit does fix the issue, at least for deserialization. |
Try cherry-picking commit GrabYourPitchforks@d7eae3b (patch file here) and see if it resolves the issue. This re-introduces the fast path in the SizeOpt files before entering the main workhorse loop. I'm hoping it won't increase size on disk significantly, but I don't have a good way of testing that right now. |
@radekdoulik can you follow up on #50260 (comment) and get us some numbers? |
I measured current HEAD and patched version of modified browser sample in Chrome. Later I added Preview 2 (no AOT as it was crashing) and reverted 197a28d measurements.
It uses the Blazor benchmark code from P2 was built on Mac and then run on the same machine/Chrome as the other sample builds. Observation: the patched version is close to reverted version and still reduces the size of the |
I have created draft PR #51310 to check the GrabYourPitchforks@d7eae3b change on CI. |
@pavelsavara how does the GrabYourPitchforks@d7eae3b and the times look to you? |
@pavelsavara Is the performance for payloads that contain non-ASCII characters (e.g. Czech strings with diacritics) important for you? (#51310 (comment)) |
@jkotas I'm newbie on the Mono team, so I don't really know. I did the original PR as part of my learning, based on GrabYourPitchforks guidance and motivated by size reduction. I don't have specific performance goal in mind. Also I think @marek-safar commented , that we could make it into (link time ?) feature flag, which could be exposed to developers, to make the choice. @radekdoulik LGTM, unless we rather do the all or nothing feature flag. |
We should get a better idea about the performance impact for non-ASCII payloads. Majority of the world uses non-ASCII characters. It is likely that the native strings that use user-local alphabet are typically going to appear in some json payloads.
I do not think the linker switch is worth it for this case. It may be worth it for other cases where the difference is more signficant. |
I think the non-ASCII will remain slow. I will try to confirm it with measurements.
Maybe we can make this size optimization be part of InvariantCulture feature switch? |
There is growing list of
|
Non-ASCII chars measurements. I have added some non-ASCII characters to the strings in the
I also wanted to measure just text, so added measurement of [de]serialization of text containing 56777 chars. (repeating pangrams in Czech language)
|
This data tells me that we should revert the size optimization change for the UTF8 encoding and take the size hit. |
…nterpreted and low-footprint scenarios (dotnet#49372)" This reverts commit 197a28d. Context: dotnet#50260
Yes, the perf hit is quite high. I have opened PR to revert it. |
Before we revert the change, should we try creating a patch which inlines the decode methods, as mentioned in another comment? Still trying to figure out if we can get a good balance of size savings & acceptable perf. But if this is bordering on contorting the code, so be it. Context: #51310 (comment) |
It's reverted for now so we don't get a ton of reports about a known regression. We can still explore the options. |
Is anybody on point for that exploration? I assume Radek, since the issue is assigned to him? |
I think investigating this encoding size optimization is in the area of diminishing returns. It would be more useful to investigate whether it is possible to make the Linq size vs. speed optimization configurable via trimming feature flag. |
Agreed, we've had customer reports of the Linq performance regression too and the size difference is larger |
On point in what sense? |
"We should explore..." Since this issue wasn't closed, I interpreted this as a request for somebody to perform this work. But it wasn't apparent to me who this work was being requested of. |
Was reverted #51379 |
Can this be closed? |
From 0f64b26...5b77db9 there was a large regression in the aspnetcore blazor json tests. That is a large span of commits because aspnetcore wasn't able to ingest the runtime for an extended period.
cc @marek-safar @danmoseley
The text was updated successfully, but these errors were encountered: