Skip to content

Commit 2fe377a

Browse files
Use TryGetValue for dictionary lookups in OpenAPI comparers (#57208)
* Use TryGetValue for dictionary lookups Use `TryGetValue()` to avoid multiple dictionary lookups in OpenAPI schema comparers. * Re-order equality comparer checks See #57208 (comment). * Check discriminators earlier Check discriminators earlier too.
1 parent 16bca05 commit 2fe377a

File tree

5 files changed

+15
-13
lines changed

5 files changed

+15
-13
lines changed

src/OpenApi/src/Comparers/OpenApiAnyComparer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public bool Equals(IOpenApiAny? x, IOpenApiAny? y)
3030
{
3131
OpenApiNull _ => y is OpenApiNull,
3232
OpenApiArray arrayX => y is OpenApiArray arrayY && arrayX.SequenceEqual(arrayY, Instance),
33-
OpenApiObject objectX => y is OpenApiObject objectY && objectX.Keys.Count == objectY.Keys.Count && objectX.Keys.All(key => objectY.ContainsKey(key) && Equals(objectX[key], objectY[key])),
33+
OpenApiObject objectX => y is OpenApiObject objectY && objectX.Keys.Count == objectY.Keys.Count && objectX.Keys.All(key => objectY.TryGetValue(key, out var yValue) && Equals(objectX[key], yValue)),
3434
OpenApiBinary binaryX => y is OpenApiBinary binaryY && binaryX.Value.SequenceEqual(binaryY.Value),
3535
OpenApiInteger integerX => y is OpenApiInteger integerY && integerX.Value == integerY.Value,
3636
OpenApiLong longX => y is OpenApiLong longY && longX.Value == longY.Value,

src/OpenApi/src/Comparers/OpenApiDiscriminatorComparer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public bool Equals(OpenApiDiscriminator? x, OpenApiDiscriminator? y)
2727

2828
return x.PropertyName == y.PropertyName &&
2929
x.Mapping.Count == y.Mapping.Count &&
30-
x.Mapping.Keys.All(key => y.Mapping.ContainsKey(key) && x.Mapping[key] == y.Mapping[key]);
30+
x.Mapping.Keys.All(key => y.Mapping.TryGetValue(key, out var yValue) && x.Mapping[key] == yValue);
3131
}
3232

3333
public int GetHashCode(OpenApiDiscriminator obj)

src/OpenApi/src/Comparers/OpenApiExternalDocsComparer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public bool Equals(OpenApiExternalDocs? x, OpenApiExternalDocs? y)
2828
return x.Description == y.Description &&
2929
x.Url == y.Url &&
3030
x.Extensions.Count == y.Extensions.Count
31-
&& x.Extensions.Keys.All(k => y.Extensions.ContainsKey(k) && y.Extensions[k] == x.Extensions[k]);
31+
&& x.Extensions.Keys.All(k => y.Extensions.TryGetValue(k, out var yValue) && yValue == x.Extensions[k]);
3232
}
3333

3434
public int GetHashCode(OpenApiExternalDocs obj)

src/OpenApi/src/Comparers/OpenApiSchemaComparer.cs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,29 @@ public bool Equals(OpenApiSchema? x, OpenApiSchema? y)
2626
return true;
2727
}
2828

29-
return Instance.Equals(x.AdditionalProperties, y.AdditionalProperties) &&
29+
// Compare property equality in an order that should help us find inequality faster
30+
return
31+
x.Type == y.Type &&
32+
x.Format == y.Format &&
33+
SchemaIdEquals(x, y) &&
34+
x.Properties.Keys.All(k => y.Properties.TryGetValue(k, out var yValue) && Instance.Equals(x.Properties[k], yValue)) &&
35+
OpenApiDiscriminatorComparer.Instance.Equals(x.Discriminator, y.Discriminator) &&
36+
Instance.Equals(x.AdditionalProperties, y.AdditionalProperties) &&
3037
x.AdditionalPropertiesAllowed == y.AdditionalPropertiesAllowed &&
3138
x.AllOf.SequenceEqual(y.AllOf, Instance) &&
3239
x.AnyOf.SequenceEqual(y.AnyOf, Instance) &&
3340
x.Deprecated == y.Deprecated &&
3441
OpenApiAnyComparer.Instance.Equals(x.Default, y.Default) &&
3542
x.Description == y.Description &&
36-
OpenApiDiscriminatorComparer.Instance.Equals(x.Discriminator, y.Discriminator) &&
3743
OpenApiAnyComparer.Instance.Equals(x.Example, y.Example) &&
3844
x.ExclusiveMaximum == y.ExclusiveMaximum &&
3945
x.ExclusiveMinimum == y.ExclusiveMinimum &&
40-
x.Extensions.Count == y.Extensions.Count
41-
&& x.Extensions.Keys.All(k => y.Extensions.ContainsKey(k) && x.Extensions[k] is IOpenApiAny anyX && y.Extensions[k] is IOpenApiAny anyY && OpenApiAnyComparer.Instance.Equals(anyX, anyY)) &&
46+
x.Extensions.Count == y.Extensions.Count &&
47+
x.Extensions.Keys.All(k => y.Extensions.TryGetValue(k, out var yValue) && x.Extensions[k] is IOpenApiAny anyX && yValue is IOpenApiAny anyY && OpenApiAnyComparer.Instance.Equals(anyX, anyY)) &&
4248
OpenApiExternalDocsComparer.Instance.Equals(x.ExternalDocs, y.ExternalDocs) &&
4349
x.Enum.SequenceEqual(y.Enum, OpenApiAnyComparer.Instance) &&
44-
x.Format == y.Format &&
4550
Instance.Equals(x.Items, y.Items) &&
4651
x.Title == y.Title &&
47-
x.Type == y.Type &&
4852
x.Maximum == y.Maximum &&
4953
x.MaxItems == y.MaxItems &&
5054
x.MaxLength == y.MaxLength &&
@@ -58,15 +62,13 @@ public bool Equals(OpenApiSchema? x, OpenApiSchema? y)
5862
Instance.Equals(x.Not, y.Not) &&
5963
x.Nullable == y.Nullable &&
6064
x.Pattern == y.Pattern &&
61-
x.Properties.Keys.All(k => y.Properties.ContainsKey(k) && Instance.Equals(x.Properties[k], y.Properties[k])) &&
6265
x.ReadOnly == y.ReadOnly &&
6366
x.Required.Order().SequenceEqual(y.Required.Order()) &&
6467
OpenApiReferenceComparer.Instance.Equals(x.Reference, y.Reference) &&
6568
x.UniqueItems == y.UniqueItems &&
6669
x.UnresolvedReference == y.UnresolvedReference &&
6770
x.WriteOnly == y.WriteOnly &&
68-
OpenApiXmlComparer.Instance.Equals(x.Xml, y.Xml) &&
69-
SchemaIdEquals(x, y);
71+
OpenApiXmlComparer.Instance.Equals(x.Xml, y.Xml);
7072
}
7173

7274
private static bool SchemaIdEquals(OpenApiSchema x, OpenApiSchema y)

src/OpenApi/src/Comparers/OpenApiXmlComparer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public bool Equals(OpenApiXml? x, OpenApiXml? y)
3131
x.Attribute == y.Attribute &&
3232
x.Wrapped == y.Wrapped &&
3333
x.Extensions.Count == y.Extensions.Count
34-
&& x.Extensions.Keys.All(k => y.Extensions.ContainsKey(k) && y.Extensions[k] == x.Extensions[k]);
34+
&& x.Extensions.Keys.All(k => y.Extensions.TryGetValue(k, out var yValue) && yValue == x.Extensions[k]);
3535
}
3636

3737
public int GetHashCode(OpenApiXml obj)

0 commit comments

Comments
 (0)