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

Add public MethodInvoker and ConstructorInvoker classes #88415

Merged
merged 6 commits into from
Jul 15, 2023

Conversation

steveharter
Copy link
Member

@steveharter steveharter commented Jul 5, 2023

Fixes #85539

Adds fixed-parameter-count and Span-based Invoke APIs for performance, primarily achieved by preventing the object[] allocation for when there are <= 4 parameters. Also, additional, faster, emit-based functions are generated for methods that don't have ref\out parameters and meet other constraints. These are also used by the existing Invoke methods so performance there has increased as well.

Todo

  • Add doc for the new public methods
  • Create PR for Mono to address unboxing a "true nullable" (currently the PR doesn't generate faster emit-based code for Mono). Done - see Enable Mono for using faster invoke stubs #89108
  • Add tests that layer on top of existing ones; currently this PR just adds a handful of new tests for the new APIs.
  • Add the new benchmarks to the performance repo

Benchmarks

Benchmarks for the new APIs. ~2.4- 3.3x faster for the 4 parameter case with no allocs. Also, these improvements would be greater but they are compared to the existing Invoke API which was also made faster here.
Method Mean Error StdDev Median Min Max Gen0 Allocated
Method0_NoParms 7.230 ns 0.0205 ns 0.0181 ns 7.228 ns 7.199 ns 7.265 ns - -
Method0_NoParms_InvokerEquivalent 6.068 ns 0.0365 ns 0.0342 ns 6.066 ns 5.994 ns 6.123 ns - -
StaticMethod4_arrayNotCached_int_string_struct_class 41.669 ns 0.2680 ns 0.2238 ns 41.627 ns 41.169 ns 41.979 ns 0.0098 104 B
StaticMethod4_int_string_struct_class_InvokerArgsEquivalent 17.156 ns 0.1327 ns 0.1242 ns 17.164 ns 17.004 ns 17.391 ns 0.0045 48 B
StaticMethod4_arrayNotCached_PreBoxed_int_string_struct_class 37.078 ns 0.2929 ns 0.2446 ns 37.064 ns 36.747 ns 37.647 ns 0.0053 56 B
StaticMethod4_arrayNotCached_PreBoxed_int_string_struct_class_InvokerArgsEquivalent 11.160 ns 0.0615 ns 0.0576 ns 11.168 ns 11.057 ns 11.244 ns - -
Benchmarks for existing Invoke APIs. Up to 1.4x faster for a property setter. Fewer allocs when >=5 parameters.
|                                                    Method |        Job |                  Toolchain |       Mean |     Error |    StdDev |     Median |        Min |        Max | Ratio | RatioSD |   Gen0 | Allocated | Alloc Ratio |
|---------------------------------------------------------- |----------- |--------------------------- |-----------:|----------:|----------:|-----------:|-----------:|-----------:|------:|--------:|-------:|----------:|------------:|
|                                           Method0_NoParms | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe |   7.625 ns | 0.0528 ns | 0.0441 ns |   7.624 ns |   7.549 ns |   7.712 ns |  1.00 |    0.00 |      - |         - |          NA |
|                                           Method0_NoParms | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe |   9.401 ns | 0.0397 ns | 0.0352 ns |   9.404 ns |   9.327 ns |   9.458 ns |  1.23 |    0.01 |      - |         - |          NA |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
|      StaticMethod4_arrayNotCached_int_string_struct_class | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe |  40.351 ns | 0.5224 ns | 0.4631 ns |  40.182 ns |  39.786 ns |  41.220 ns |  1.00 |    0.00 | 0.0099 |     104 B |        1.00 |
|      StaticMethod4_arrayNotCached_int_string_struct_class | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe |  49.067 ns | 0.9783 ns | 1.0468 ns |  48.853 ns |  47.515 ns |  51.704 ns |  1.22 |    0.03 | 0.0098 |     104 B |        1.00 |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
| StaticMethod5_arrayNotCached_int_string_struct_class_bool | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe |  56.730 ns | 0.5781 ns | 0.5408 ns |  56.669 ns |  55.909 ns |  57.890 ns |  1.00 |    0.00 | 0.0128 |     136 B |        1.00 |
| StaticMethod5_arrayNotCached_int_string_struct_class_bool | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe |  74.827 ns | 1.6601 ns | 1.8452 ns |  74.496 ns |  71.119 ns |  78.316 ns |  1.32 |    0.03 | 0.0191 |     200 B |        1.47 |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
|                     StaticMethod4_int_string_struct_class | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe |  28.537 ns | 0.2502 ns | 0.2218 ns |  28.585 ns |  28.185 ns |  28.842 ns |  1.00 |    0.00 |      - |         - |          NA |
|                     StaticMethod4_int_string_struct_class | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe |  34.938 ns | 0.1109 ns | 0.0983 ns |  34.899 ns |  34.821 ns |  35.179 ns |  1.22 |    0.01 |      - |         - |          NA |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
|         StaticMethod4_ByRefParams_int_string_struct_class | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe | 144.779 ns | 1.0213 ns | 0.9054 ns | 144.673 ns | 142.893 ns | 146.116 ns |  1.00 |    0.00 | 0.0041 |      48 B |        1.00 |
|         StaticMethod4_ByRefParams_int_string_struct_class | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe | 138.456 ns | 0.2052 ns | 0.1714 ns | 138.511 ns | 138.134 ns | 138.783 ns |  0.96 |    0.01 | 0.0043 |      48 B |        1.00 |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
|    StaticMethod5_ByRefParams_int_string_struct_class_bool | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe | 196.652 ns | 1.2706 ns | 1.1885 ns | 196.883 ns | 194.293 ns | 198.425 ns |  1.00 |    0.00 | 0.0063 |      72 B |        1.00 |
|    StaticMethod5_ByRefParams_int_string_struct_class_bool | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe | 193.105 ns | 1.0413 ns | 0.8696 ns | 193.156 ns | 191.592 ns | 194.599 ns |  0.98 |    0.01 | 0.0123 |     136 B |        1.89 |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
|                                            Ctor0_NoParams | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe |   9.128 ns | 0.0912 ns | 0.0853 ns |   9.137 ns |   9.005 ns |   9.264 ns |  1.00 |    0.00 | 0.0053 |      56 B |        1.00 |
|                                            Ctor0_NoParams | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe |  11.096 ns | 0.1013 ns | 0.0947 ns |  11.085 ns |  10.965 ns |  11.262 ns |  1.22 |    0.02 | 0.0053 |      56 B |        1.00 |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
|                             Ctor4_int_string_struct_class | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe |  32.506 ns | 0.2559 ns | 0.2137 ns |  32.561 ns |  32.026 ns |  32.865 ns |  1.00 |    0.00 | 0.0053 |      56 B |        1.00 |
|                             Ctor4_int_string_struct_class | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe |  39.152 ns | 0.2872 ns | 0.2687 ns |  39.151 ns |  38.818 ns |  39.719 ns |  1.20 |    0.01 | 0.0052 |      56 B |        1.00 |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
|                                          Property_Get_int | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe |  10.565 ns | 0.1276 ns | 0.1131 ns |  10.581 ns |  10.416 ns |  10.833 ns |  1.00 |    0.00 | 0.0023 |      24 B |        1.00 |
|                                          Property_Get_int | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe |  12.435 ns | 0.0953 ns | 0.0845 ns |  12.432 ns |  12.299 ns |  12.604 ns |  1.18 |    0.01 | 0.0023 |      24 B |        1.00 |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
|                                        Property_Get_class | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe |   8.091 ns | 0.0468 ns | 0.0415 ns |   8.093 ns |   8.037 ns |   8.178 ns |  1.00 |    0.00 |      - |         - |          NA |
|                                        Property_Get_class | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe |  10.549 ns | 0.0877 ns | 0.0778 ns |  10.555 ns |  10.411 ns |  10.685 ns |  1.30 |    0.01 |      - |         - |          NA |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
|                                          Property_Set_int | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe |  16.105 ns | 0.1308 ns | 0.1160 ns |  16.110 ns |  15.916 ns |  16.325 ns |  1.00 |    0.00 | 0.0023 |      24 B |        1.00 |
|                                          Property_Set_int | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe |  21.829 ns | 0.4245 ns | 0.3971 ns |  21.916 ns |  21.035 ns |  22.320 ns |  1.35 |    0.03 | 0.0022 |      24 B |        1.00 |
|                                                           |            |                            |            |           |           |            |            |            |       |         |        |           |             |
|                                        Property_Set_class | Job-MZSTNH |  \INVOKE_AFTER\corerun.exe |  13.299 ns | 0.0699 ns | 0.0654 ns |  13.304 ns |  13.209 ns |  13.383 ns |  1.00 |    0.00 |      - |         - |          NA |
|                                        Property_Set_class | Job-UYFZWZ | \INVOKE_BEFORE\corerun.exe |  18.799 ns | 0.1101 ns | 0.1030 ns |  18.764 ns |  18.636 ns |  19.001 ns |  1.41 |    0.01 |      - |         - |          NA |
Benchmarks for NativeAot. ~1.3-1.7x faster when using the new APIs
old 0 args: 1014
new 0 args:  595
old 1 arg: 4860
new 1 arg: 3319
old 2 args:7595
new 2 args:5875
old 5 args:16292
new 5 args:15325

@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 Jul 5, 2023

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

Issue Details

[wip]

Author: steveharter
Assignees: steveharter
Labels:

area-System.Reflection

Milestone: -

src/coreclr/vm/ecalllist.h Outdated Show resolved Hide resolved
Copy link
Contributor

@buyaa-n buyaa-n left a comment

Choose a reason for hiding this comment

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

Left a few NITs, overall looks good to me.

RuntimeType sigType = _argTypes[i];

// Convert the type if necessary.
// Note that Type.Missing is not supported.
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: By assuming this applyes to all new Invoke methods, this might be good to be added to the public doc

@steveharter steveharter merged commit 0a587ff into dotnet:main Jul 15, 2023
165 of 168 checks passed
@steveharter steveharter deleted the AddMethodInvoker branch July 15, 2023 01:35
@cincuranet
Copy link
Contributor

Improvement in dotnet/perf-autofiling-issues#19968.

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.

[API Proposal]: Add invoker classes for fast invoke APIs
5 participants