-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Options generator perf improvements #91073
Comments
Tagging subscribers to this area: @dotnet/area-system-componentmodel-dataannotations Issue DetailsThe options generator is emitting code like this: var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + ".";
var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder();
var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options);
var validationResults = new global::System.Collections.Generic.List<global::System.ComponentModel.DataAnnotations.ValidationResult>();
var validationAttributes = new global::System.Collections.Generic.List<global::System.ComponentModel.DataAnnotations.ValidationAttribute>(1);
context.MemberName = "P1";
context.DisplayName = baseName + "P1";
validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3);
if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes))
{
builder.AddResults(validationResults);
}
context.MemberName = "P2";
context.DisplayName = baseName + "P2";
validationResults.Clear();
validationAttributes.Clear();
validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4);
if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2!, context, validationResults, validationAttributes))
{
builder.AddResults(validationResults);
}
return builder.Build();
|
Tagging subscribers to this area: @dotnet/area-extensions-options Issue DetailsThe options generator is emitting code like this: var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + ".";
var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder();
var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options);
var validationResults = new global::System.Collections.Generic.List<global::System.ComponentModel.DataAnnotations.ValidationResult>();
var validationAttributes = new global::System.Collections.Generic.List<global::System.ComponentModel.DataAnnotations.ValidationAttribute>(1);
context.MemberName = "P1";
context.DisplayName = baseName + "P1";
validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3);
if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes))
{
builder.AddResults(validationResults);
}
context.MemberName = "P2";
context.DisplayName = baseName + "P2";
validationResults.Clear();
validationAttributes.Clear();
validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4);
if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2!, context, validationResults, validationAttributes))
{
builder.AddResults(validationResults);
}
return builder.Build();
|
cc @tarekgh. |
This is fixed by #91432 |
The options generator is emitting code like this:
baseName
, even in the common case where name is null and both things being concatenated are literals. There's then another concatenation allocation per member, as the implementation tacks on a literal suffix. Instead ofvar baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + ".";
, that line should be deleted, the each display name creation should instead be like:context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P2" : name + ".P2";
. That way, when the name is null or empty, there are zero string allocations, and when the name is non-null and non-empty, it saves the one intermediate allocation.ValidateOptionsResultBuilder
is a class and is being allocated even when there aren't any validation errors. We should instead lazily allocate it only when one of the TryValidateValue calls returns false.The text was updated successfully, but these errors were encountered: