- Notifications
You must be signed in to change notification settings - Fork 413
Perf improvements part 6: startup time #1654
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
Conversation
…st common scenarios
… methods for it. -3ms for startup!
…vided (0.4 ms of JIT time)
…ple (struct). -4 JIT compilaitons
…educe the number of compilations and type loading
… time ArgumentConverter was used, no matter if we wanted to create a list or not)
# Conflicts: # src/System.CommandLine/Binding/ArgumentConverter.cs
src/System.CommandLine/Binding/ArgumentConverter.DefaultValues.cs Outdated Show resolved Hide resolved
src/System.CommandLine/Binding/ArgumentConverter.DefaultValues.cs Outdated Show resolved Hide resolved
| { | ||
| #if NET6_0_OR_GREATER | ||
| var ctor = (ConstructorInfo)listType.GetMemberWithSameMetadataDefinitionAs(_listCtor.Value); | ||
| ConstructorInfo? listCtor = _listCtor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there reflection-based argument conversions used with the source generator support?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Source generator support is still pending. The original source generator work we did was superseded by improvements we've made to support trimming.
| argument, | ||
| argument.Arity.MinimumNumberOfValues, | ||
| argument.Arity.MaximumNumberOfValues) is ArgumentConversionResult failed && | ||
| failed is not null) // returns null on success |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
failed is not null check isn't needed. I think it's redundant with is ArgumentConversionResult failed which won't match if the return value of Validate is null.
The best way to review this PR is most probably to look at each commit separately. The changes belong to few categories:
ICommandHandlerwith synchronousInvokemethod: this allows to avoid the need of loading and jitting all async machinery for users who don't want to useasyncoverloads (I would imagine that most users don't need it as async should be used for potentially blocking IO operations)static Lazy<T>fields, which get jitted when given type is referenced for the firs time. I've just moved the logic to getters and it's compiled when it's used. In worst case scenario users who for some reason use multiple threads to parse command line args are going to duplicate the initialization work.structs. Every struct is of a different size and because of that, the JIT compiler needs to prepare a dedicated version of each generic collection (or other generic type that uses struct and type argument) for each unique value type. ChangingTokenfromstructtoclassreduced the number of JIT compilations reported by Perfview by 20!For the following app that mimics @jkotas example:
the total execution time measured with
Measure-Commandfor--bool true -s testarguments went down from 73 ms to 60-62 ms (Windows)