-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Closed
Closed
Copy link
Labels
arch-wasmWebAssembly architectureWebAssembly architecturearea-Codegen-Interpreter-monotenet-performancePerformance related issuePerformance related issue
Milestone
Description
Description
The way Dictionary and GenericEqualityComparer interact causes performance issues in the Jiterpreter that would be hard to fix without changes to the interpreter and/or the BCL. For more details see dotnet/perf-autofiling-issues#12762 (comment) but to summarize:
The Dictionary<int, int>.ContainsValue benchmark regressed once the jiterpreter was enabled.
- Dictionary.ContainsValue is written assuming multiple optimizations will happen, and very few (or none) of them happen in this configuration
GenericEqualityComparer<int>
is used for the benchmark that regressed and it is also very inefficient in this configuration- The result is slow mono interpreter opcodes that also hit some of the jiterpreter's worst case scenarios
- It is difficult (perhaps impossible) to fix this on the jiterpreter side, the regression can probably be made smaller but eliminating it would require blocking compilation for Dictionary and perhaps GenericEqualityComparer. I am unable to imagine a heuristic that would detect this reliably.
Configuration
This applies to WebAssembly non-AOT (mono interpreter) with the jiterpreter enabled.
Regression?
Performance regresses for this code with the jiterpreter enabled
Data
Analysis
Candidate changes that might entirely make this go away, while also just making these code paths faster in the mono interpreter:
- Turn typeof(T).IsValueType into a constant when generating code in the interpreter (does this happen already? I can't tell for sure), then do DCE based on it to reduce the amount of code in the method. This doesn't seem easy to me.
- Move the comparison against null to only happen after we've checked whether T is a ValueType. The comparisons against null cause the value to be boxed.
- Introduce a GenericValueTypeEqualityComparer. Its equals method will not contain boxing (much faster!) and will be smaller, which might cause it to get inlined. It does already have AggressiveInlining applied to it, but it's not inlined in this case.
- Define a special comparer for int, like we already did for byte. This might also allow the comparison to get inlined here, and int is a pretty common type to use as a key or value in containers so it makes sense to have a dedicated comparer for it.
Metadata
Metadata
Assignees
Labels
arch-wasmWebAssembly architectureWebAssembly architecturearea-Codegen-Interpreter-monotenet-performancePerformance related issuePerformance related issue