From b7c79176b480511895c82ab72b8936fd24fab8f2 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 29 Jun 2026 15:25:11 -0400 Subject: [PATCH 1/3] tests: adds a negative test for external anchors feat: adds support for relative ids Signed-off-by: Vincent Biret --- .../Services/OpenApiWorkspace.cs | 70 +++++++++- .../V31Tests/RelativeReferenceTests.cs | 121 +++++++++++++++++ .../V32Tests/RelativeReferenceTests.cs | 122 +++++++++++++++++- 3 files changed, 308 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs index 4849f1a42..09c75be49 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs @@ -97,10 +97,7 @@ public void RegisterComponents(OpenApiDocument document) location = baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); - if (item.Value is not OpenApiSchemaReference && item.Value.Id is string schemaId && schemaId.Length > 0) - { - RegisterComponent(schemaId, item.Value); - } + RegisterSchemaIdentifiers(item.Value, document.BaseUri); } } @@ -288,6 +285,71 @@ internal bool RegisterComponent(string location, T component) return false; } + private void RegisterSchemaIdentifiers(IOpenApiSchema schema, Uri baseUri) + { + RegisterSchemaIdentifiers(schema, baseUri, new HashSet()); + } + + private void RegisterSchemaIdentifiers(IOpenApiSchema schema, Uri baseUri, ISet visitedSchemas) + { + if (schema is OpenApiSchemaReference || !visitedSchemas.Add(schema)) + { + return; + } + + var schemaBaseUri = baseUri; + if (!string.IsNullOrEmpty(schema.Id) && + Uri.TryCreate(schema.Id, UriKind.RelativeOrAbsolute, out var schemaIdUri)) + { + schemaBaseUri = schemaIdUri.IsAbsoluteUri ? schemaIdUri : new Uri(baseUri, schemaIdUri); + RegisterComponent(schemaBaseUri.AbsoluteUri, schema); + } + + RegisterSchemaIdentifier(schema.Items, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifier(schema.AdditionalProperties, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifier(schema.Not, schemaBaseUri, visitedSchemas); + + RegisterSchemaIdentifiers(schema.Properties?.Values, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifiers(schema.PatternProperties?.Values, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifiers(schema.Definitions?.Values, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifiers(schema.AllOf, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifiers(schema.AnyOf, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifiers(schema.OneOf, schemaBaseUri, visitedSchemas); + + if (schema is IOpenApiSchemaMissingProperties missingProperties) + { + RegisterSchemaIdentifier(missingProperties.Contains, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifier(missingProperties.PropertyNames, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifier(missingProperties.UnevaluatedPropertiesSchema, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifier(missingProperties.ContentSchema, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifier(missingProperties.If, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifier(missingProperties.Then, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifier(missingProperties.Else, schemaBaseUri, visitedSchemas); + RegisterSchemaIdentifiers(missingProperties.DependentSchemas?.Values, schemaBaseUri, visitedSchemas); + } + } + + private void RegisterSchemaIdentifiers(IEnumerable? schemas, Uri baseUri, ISet visitedSchemas) + { + if (schemas is null) + { + return; + } + + foreach (var schema in schemas) + { + RegisterSchemaIdentifiers(schema, baseUri, visitedSchemas); + } + } + + private void RegisterSchemaIdentifier(IOpenApiSchema? schema, Uri baseUri, ISet visitedSchemas) + { + if (schema is not null) + { + RegisterSchemaIdentifiers(schema, baseUri, visitedSchemas); + } + } + /// /// Adds a document id to the dictionaries of document locations and their ids. /// diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs index 070fff68c..2d47a901a 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs @@ -172,6 +172,76 @@ public async Task ParseExternalComponentSubschemaJsonSchemaReferenceWorks() Assert.Equal(JsonSchemaType.Object, schema.Type); } + [Theory] + [InlineData("OAS-schemas.yaml#address", @" +openapi: 3.1.0 +info: + title: OpenAPI document containing reusable components + version: 1.0.0 +components: + schemas: + person: + type: object + properties: + address: + $anchor: address + type: object +")] + [InlineData("OAS-schemas.yaml#/person/properties/address", @" +person: + type: object + properties: + address: + type: object +")] + public async Task UnsupportedExternalJsonSchemaLocatorReferenceDoesNotResolve(string reference, string externalDocument) + { + var tempDirectory = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(tempDirectory); + + var rootPath = Path.Join(tempDirectory, "root.yaml"); + var externalPath = Path.Join(tempDirectory, "OAS-schemas.yaml"); + + await File.WriteAllTextAsync(rootPath, + $@"openapi: 3.1.0 +info: + title: T + version: 1.0.0 +paths: + /person/{{id}}: + get: + responses: + '200': + description: ok + content: + application/json: + schema: + $ref: '{reference}' +"); + await File.WriteAllTextAsync(externalPath, externalDocument); + + try + { + var settings = new OpenApiReaderSettings + { + LoadExternalRefs = true, + BaseUrl = new Uri(rootPath), + }; + settings.AddYamlReader(); + + var result = await OpenApiDocument.LoadAsync(rootPath, settings); + var schema = result.Document.Paths["/person/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; + var schemaReference = Assert.IsType(schema); + + Assert.True(schemaReference.UnresolvedReference); + Assert.Null(schema.Type); + } + finally + { + Directory.Delete(tempDirectory, true); + } + } + [Fact] public async Task ParseReferenceToInternalComponentUsingDollarIdWorks() { @@ -186,6 +256,57 @@ public async Task ParseReferenceToInternalComponentUsingDollarIdWorks() Assert.Equal(JsonSchemaType.Object, schema.Type); } + [Fact] + public async Task ParseReferenceToInternalSubschemaUsingDollarIdWorks() + { + var tempDirectory = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(tempDirectory); + + var rootPath = Path.Join(tempDirectory, "root.yaml"); + + await File.WriteAllTextAsync(rootPath, + @"openapi: 3.1.0 +info: + title: T + version: 1.0.0 +paths: + /person/{id}/address: + get: + responses: + '200': + description: ok + content: + application/json: + schema: + $ref: 'https://schemas.acme.org/address' +components: + schemas: + person: + $id: 'https://schemas.acme.org/person' + type: object + properties: + address: + $id: 'address' + type: object + properties: + street: + type: string +"); + + try + { + var result = await OpenApiDocument.LoadAsync(rootPath, SettingsFixture.ReaderSettings); + var schema = result.Document.Paths["/person/{id}/address"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; + + Assert.Equal(JsonSchemaType.Object, schema.Type); + Assert.Equal(JsonSchemaType.String, schema.Properties["street"].Type); + } + finally + { + Directory.Delete(tempDirectory, true); + } + } + [Fact] public async Task ParseLocalReferenceToJsonSchemaResourceWorks() { diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/RelativeReferenceTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/RelativeReferenceTests.cs index 2171f35aa..9ed2e533d 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/RelativeReferenceTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/RelativeReferenceTests.cs @@ -172,6 +172,76 @@ public async Task ParseExternalComponentSubschemaJsonSchemaReferenceWorks() Assert.Equal(JsonSchemaType.Object, schema.Type); } + [Theory] + [InlineData("OAS-schemas.yaml#address", @" +openapi: 3.2.0 +info: + title: OpenAPI document containing reusable components + version: 1.0.0 +components: + schemas: + person: + type: object + properties: + address: + $anchor: address + type: object +")] + [InlineData("OAS-schemas.yaml#/person/properties/address", @" +person: + type: object + properties: + address: + type: object +")] + public async Task UnsupportedExternalJsonSchemaLocatorReferenceDoesNotResolve(string reference, string externalDocument) + { + var tempDirectory = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(tempDirectory); + + var rootPath = Path.Join(tempDirectory, "root.yaml"); + var externalPath = Path.Join(tempDirectory, "OAS-schemas.yaml"); + + await File.WriteAllTextAsync(rootPath, + $@"openapi: 3.2.0 +info: + title: T + version: 1.0.0 +paths: + /person/{{id}}: + get: + responses: + '200': + description: ok + content: + application/json: + schema: + $ref: '{reference}' +"); + await File.WriteAllTextAsync(externalPath, externalDocument); + + try + { + var settings = new OpenApiReaderSettings + { + LoadExternalRefs = true, + BaseUrl = new Uri(rootPath), + }; + settings.AddYamlReader(); + + var result = await OpenApiDocument.LoadAsync(rootPath, settings); + var schema = result.Document.Paths["/person/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; + var schemaReference = Assert.IsType(schema); + + Assert.True(schemaReference.UnresolvedReference); + Assert.Null(schema.Type); + } + finally + { + Directory.Delete(tempDirectory, true); + } + } + [Fact] public async Task ParseReferenceToInternalComponentUsingDollarIdWorks() { @@ -186,6 +256,57 @@ public async Task ParseReferenceToInternalComponentUsingDollarIdWorks() Assert.Equal(JsonSchemaType.Object, schema.Type); } + [Fact] + public async Task ParseReferenceToInternalSubschemaUsingDollarIdWorks() + { + var tempDirectory = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(tempDirectory); + + var rootPath = Path.Join(tempDirectory, "root.yaml"); + + await File.WriteAllTextAsync(rootPath, + @"openapi: 3.2.0 +info: + title: T + version: 1.0.0 +paths: + /person/{id}/address: + get: + responses: + '200': + description: ok + content: + application/json: + schema: + $ref: 'https://schemas.acme.org/address' +components: + schemas: + person: + $id: 'https://schemas.acme.org/person' + type: object + properties: + address: + $id: 'address' + type: object + properties: + street: + type: string +"); + + try + { + var result = await OpenApiDocument.LoadAsync(rootPath, SettingsFixture.ReaderSettings); + var schema = result.Document.Paths["/person/{id}/address"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; + + Assert.Equal(JsonSchemaType.Object, schema.Type); + Assert.Equal(JsonSchemaType.String, schema.Properties["street"].Type); + } + finally + { + Directory.Delete(tempDirectory, true); + } + } + [Fact] public async Task ParseLocalReferenceToJsonSchemaResourceWorks() { @@ -512,4 +633,3 @@ public void ExitsEarlyOnCyclicalReferences() } } } - From 801084d0dd32ac9b9165fbff91ad3c2e9d85c197 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 29 Jun 2026 15:27:42 -0400 Subject: [PATCH 2/3] feat: adds support for external anchors Signed-off-by: Vincent Biret --- .../Models/OpenApiDocument.cs | 21 ++++- .../Services/OpenApiWorkspace.cs | 14 ++++ .../V31Tests/RelativeReferenceTests.cs | 77 +++++++++++++++---- .../V32Tests/RelativeReferenceTests.cs | 77 +++++++++++++++---- 4 files changed, 158 insertions(+), 31 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 62a1afa22..1f471981b 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -639,7 +639,11 @@ private static string ConvertByteArrayToString(byte[] hash) string relativePath; var referenceV3 = !string.IsNullOrEmpty(reference.ReferenceV3) ? reference.ReferenceV3! : string.Empty; - if (!string.IsNullOrEmpty(referenceV3) && IsSubComponent(referenceV3)) + if (reference.Type is ReferenceType.Schema && useExternal && TryGetPlainNameFragment(referenceV3, out var plainNameFragment)) + { + relativePath = plainNameFragment; + } + else if (!string.IsNullOrEmpty(referenceV3) && IsSubComponent(referenceV3)) { // Enables setting the complete JSON path for nested subschemas e.g. #/components/schemas/person/properties/address if (useExternal) @@ -702,6 +706,21 @@ private static bool IsSubComponent(string reference) return false; } + private static bool TryGetPlainNameFragment(string reference, out string fragment) + { + fragment = string.Empty; + var parts = reference.Split('#'); + if (parts.Length == 2 && + !string.IsNullOrEmpty(parts[1]) && + !parts[1].StartsWith("/", StringComparison.Ordinal)) + { + fragment = $"#{parts[1]}"; + return true; + } + + return false; + } + /// /// Reads the stream input and parses it into an Open API document. /// diff --git a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs index 09c75be49..0d98abeb8 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs @@ -298,6 +298,15 @@ private void RegisterSchemaIdentifiers(IOpenApiSchema schema, Uri baseUri, ISet< } var schemaBaseUri = baseUri; + if (schema is IOpenApiSchemaMissingProperties { Anchor.Length: > 0 } schemaWithAnchor) + { + var anchorUriBuilder = new UriBuilder(schemaBaseUri) + { + Fragment = schemaWithAnchor.Anchor + }; + RegisterComponent(anchorUriBuilder.Uri.AbsoluteUri, schema); + } + if (!string.IsNullOrEmpty(schema.Id) && Uri.TryCreate(schema.Id, UriKind.RelativeOrAbsolute, out var schemaIdUri)) { @@ -432,6 +441,11 @@ public bool Contains(string location) if (string.IsNullOrEmpty(location) || ToLocationUrl(location) is not Uri uri) return default; + if (!string.IsNullOrEmpty(uri.Fragment) && !uri.Fragment.StartsWith("#/", StringComparison.Ordinal)) + { + return ResolveReference(location); + } + #if NETSTANDARD2_1 || NETCOREAPP || NET5_0_OR_GREATER if (!location.Contains("#/components/schemas/", StringComparison.OrdinalIgnoreCase)) #else diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs index 2d47a901a..4eebac2f5 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs @@ -172,8 +172,33 @@ public async Task ParseExternalComponentSubschemaJsonSchemaReferenceWorks() Assert.Equal(JsonSchemaType.Object, schema.Type); } - [Theory] - [InlineData("OAS-schemas.yaml#address", @" + [Fact] + public async Task ParseExternalInlineSubschemaUsingAnchorWorks() + { + var tempDirectory = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(tempDirectory); + + var rootPath = Path.Join(tempDirectory, "root.yaml"); + var externalPath = Path.Join(tempDirectory, "OAS-schemas.yaml"); + + await File.WriteAllTextAsync(rootPath, + @"openapi: 3.1.0 +info: + title: T + version: 1.0.0 +paths: + /person/{id}: + get: + responses: + '200': + description: ok + content: + application/json: + schema: + $ref: 'OAS-schemas.yaml#address' +"); + await File.WriteAllTextAsync(externalPath, + @" openapi: 3.1.0 info: title: OpenAPI document containing reusable components @@ -186,15 +211,30 @@ public async Task ParseExternalComponentSubschemaJsonSchemaReferenceWorks() address: $anchor: address type: object -")] - [InlineData("OAS-schemas.yaml#/person/properties/address", @" -person: - type: object - properties: - address: - type: object -")] - public async Task UnsupportedExternalJsonSchemaLocatorReferenceDoesNotResolve(string reference, string externalDocument) +"); + + try + { + var settings = new OpenApiReaderSettings + { + LoadExternalRefs = true, + BaseUrl = new Uri(rootPath), + }; + settings.AddYamlReader(); + + var result = await OpenApiDocument.LoadAsync(rootPath, settings); + var schema = result.Document.Paths["/person/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; + + Assert.Equal(JsonSchemaType.Object, schema.Type); + } + finally + { + Directory.Delete(tempDirectory, true); + } + } + + [Fact] + public async Task ExternalJsonSchemaFragmentReferenceDoesNotResolve() { var tempDirectory = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString("N")); Directory.CreateDirectory(tempDirectory); @@ -203,12 +243,12 @@ public async Task UnsupportedExternalJsonSchemaLocatorReferenceDoesNotResolve(st var externalPath = Path.Join(tempDirectory, "OAS-schemas.yaml"); await File.WriteAllTextAsync(rootPath, - $@"openapi: 3.1.0 + @"openapi: 3.1.0 info: title: T version: 1.0.0 paths: - /person/{{id}}: + /person/{id}: get: responses: '200': @@ -216,9 +256,16 @@ await File.WriteAllTextAsync(rootPath, content: application/json: schema: - $ref: '{reference}' + $ref: 'OAS-schemas.yaml#/person/properties/address' +"); + await File.WriteAllTextAsync(externalPath, + @" +person: + type: object + properties: + address: + type: object "); - await File.WriteAllTextAsync(externalPath, externalDocument); try { diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/RelativeReferenceTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/RelativeReferenceTests.cs index 9ed2e533d..7b53c9688 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/RelativeReferenceTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/RelativeReferenceTests.cs @@ -172,8 +172,33 @@ public async Task ParseExternalComponentSubschemaJsonSchemaReferenceWorks() Assert.Equal(JsonSchemaType.Object, schema.Type); } - [Theory] - [InlineData("OAS-schemas.yaml#address", @" + [Fact] + public async Task ParseExternalInlineSubschemaUsingAnchorWorks() + { + var tempDirectory = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(tempDirectory); + + var rootPath = Path.Join(tempDirectory, "root.yaml"); + var externalPath = Path.Join(tempDirectory, "OAS-schemas.yaml"); + + await File.WriteAllTextAsync(rootPath, + @"openapi: 3.2.0 +info: + title: T + version: 1.0.0 +paths: + /person/{id}: + get: + responses: + '200': + description: ok + content: + application/json: + schema: + $ref: 'OAS-schemas.yaml#address' +"); + await File.WriteAllTextAsync(externalPath, + @" openapi: 3.2.0 info: title: OpenAPI document containing reusable components @@ -186,15 +211,30 @@ public async Task ParseExternalComponentSubschemaJsonSchemaReferenceWorks() address: $anchor: address type: object -")] - [InlineData("OAS-schemas.yaml#/person/properties/address", @" -person: - type: object - properties: - address: - type: object -")] - public async Task UnsupportedExternalJsonSchemaLocatorReferenceDoesNotResolve(string reference, string externalDocument) +"); + + try + { + var settings = new OpenApiReaderSettings + { + LoadExternalRefs = true, + BaseUrl = new Uri(rootPath), + }; + settings.AddYamlReader(); + + var result = await OpenApiDocument.LoadAsync(rootPath, settings); + var schema = result.Document.Paths["/person/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema; + + Assert.Equal(JsonSchemaType.Object, schema.Type); + } + finally + { + Directory.Delete(tempDirectory, true); + } + } + + [Fact] + public async Task ExternalJsonSchemaFragmentReferenceDoesNotResolve() { var tempDirectory = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString("N")); Directory.CreateDirectory(tempDirectory); @@ -203,12 +243,12 @@ public async Task UnsupportedExternalJsonSchemaLocatorReferenceDoesNotResolve(st var externalPath = Path.Join(tempDirectory, "OAS-schemas.yaml"); await File.WriteAllTextAsync(rootPath, - $@"openapi: 3.2.0 + @"openapi: 3.2.0 info: title: T version: 1.0.0 paths: - /person/{{id}}: + /person/{id}: get: responses: '200': @@ -216,9 +256,16 @@ await File.WriteAllTextAsync(rootPath, content: application/json: schema: - $ref: '{reference}' + $ref: 'OAS-schemas.yaml#/person/properties/address' +"); + await File.WriteAllTextAsync(externalPath, + @" +person: + type: object + properties: + address: + type: object "); - await File.WriteAllTextAsync(externalPath, externalDocument); try { From c62d21f30fdfc1b4086318da51ecfcfc605b5a42 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Jun 2026 20:15:18 +0000 Subject: [PATCH 3/3] chore(benchmark): update performance reports --- .../performance.Descriptions-report-github.md | 24 +++---- .../performance.Descriptions-report.csv | 12 ++-- .../performance.Descriptions-report.html | 24 +++---- .../performance.Descriptions-report.json | 2 +- .../performance.EmptyModels-report-github.md | 68 +++++++++---------- .../performance.EmptyModels-report.csv | 56 +++++++-------- .../performance.EmptyModels-report.html | 68 +++++++++---------- .../performance.EmptyModels-report.json | 2 +- 8 files changed, 128 insertions(+), 128 deletions(-) diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md index 9b377334f..13e3500c6 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md @@ -1,20 +1,20 @@ ``` -BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8655/25H2/2025Update/HudsonValley2) -Snapdragon X 12-core X1E80100 3.40 GHz (Max: 3.42GHz), 1 CPU, 12 logical and 12 physical cores +BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat) +AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores .NET SDK 10.0.301 - [Host] : .NET 8.0.28 (8.0.28, 8.0.2826.26413), Arm64 RyuJIT armv8.0-a - ShortRun : .NET 8.0.28 (8.0.28, 8.0.2826.26413), Arm64 RyuJIT armv8.0-a + [Host] : .NET 8.0.28 (8.0.28, 8.0.2826.26413), X64 RyuJIT x86-64-v3 + ShortRun : .NET 8.0.28 (8.0.28, 8.0.2826.26413), X64 RyuJIT x86-64-v3 Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3 ``` -| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | -|------------- |-------------:|--------------:|-------------:|-----------:|-----------:|----------:|-------------:| -| PetStoreYaml | 275.7 μs | 16.56 μs | 0.91 μs | 76.1719 | 13.6719 | - | 313.5 KB | -| PetStoreJson | 120.8 μs | 3.75 μs | 0.21 μs | 42.9688 | 10.7422 | - | 175.64 KB | -| GHESYaml | 633,787.7 μs | 233,432.08 μs | 12,795.20 μs | 45000.0000 | 19000.0000 | 3000.0000 | 254632.89 KB | -| GHESJson | 237,577.2 μs | 200,872.43 μs | 11,010.50 μs | 18000.0000 | 9000.0000 | 2000.0000 | 111804.38 KB | -| GHESNextYaml | 788,550.2 μs | 630,692.15 μs | 34,570.36 μs | 79000.0000 | 20000.0000 | 3000.0000 | 450741.24 KB | -| GHESNextJson | 482,486.5 μs | 298,619.77 μs | 16,368.36 μs | 53000.0000 | 13000.0000 | 3000.0000 | 312508.07 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|------------- |---------------:|--------------:|-------------:|-----------:|-----------:|----------:|-------------:| +| PetStoreYaml | 491.4 μs | 72.31 μs | 3.96 μs | 18.5547 | 3.9063 | - | 314.57 KB | +| PetStoreJson | 199.4 μs | 19.87 μs | 1.09 μs | 10.7422 | 2.9297 | - | 176.42 KB | +| GHESYaml | 939,520.0 μs | 187,454.80 μs | 10,275.03 μs | 18000.0000 | 17000.0000 | 3000.0000 | 256688.91 KB | +| GHESJson | 282,084.8 μs | 100,501.66 μs | 5,508.84 μs | 6000.0000 | 5000.0000 | 1000.0000 | 113857.84 KB | +| GHESNextYaml | 1,152,354.7 μs | 45,814.56 μs | 2,511.25 μs | 30000.0000 | 18000.0000 | 3000.0000 | 452765.4 KB | +| GHESNextJson | 549,904.6 μs | 80,767.59 μs | 4,427.14 μs | 20000.0000 | 10000.0000 | 2000.0000 | 314529.52 KB | diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv index 1a46d3ec9..e390112ab 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv @@ -1,7 +1,7 @@ Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Gen0,Gen1,Gen2,Allocated -PetStoreYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,275.7 μs,16.56 μs,0.91 μs,76.1719,13.6719,0.0000,313.5 KB -PetStoreJson,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,120.8 μs,3.75 μs,0.21 μs,42.9688,10.7422,0.0000,175.64 KB -GHESYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"633,787.7 μs","233,432.08 μs","12,795.20 μs",45000.0000,19000.0000,3000.0000,254632.89 KB -GHESJson,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"237,577.2 μs","200,872.43 μs","11,010.50 μs",18000.0000,9000.0000,2000.0000,111804.38 KB -GHESNextYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"788,550.2 μs","630,692.15 μs","34,570.36 μs",79000.0000,20000.0000,3000.0000,450741.24 KB -GHESNextJson,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"482,486.5 μs","298,619.77 μs","16,368.36 μs",53000.0000,13000.0000,3000.0000,312508.07 KB +PetStoreYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,491.4 μs,72.31 μs,3.96 μs,18.5547,3.9063,0.0000,314.57 KB +PetStoreJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,199.4 μs,19.87 μs,1.09 μs,10.7422,2.9297,0.0000,176.42 KB +GHESYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"939,520.0 μs","187,454.80 μs","10,275.03 μs",18000.0000,17000.0000,3000.0000,256688.91 KB +GHESJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"282,084.8 μs","100,501.66 μs","5,508.84 μs",6000.0000,5000.0000,1000.0000,113857.84 KB +GHESNextYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"1,152,354.7 μs","45,814.56 μs","2,511.25 μs",30000.0000,18000.0000,3000.0000,452765.4 KB +GHESNextJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"549,904.6 μs","80,767.59 μs","4,427.14 μs",20000.0000,10000.0000,2000.0000,314529.52 KB diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html index 3024ef8c2..c95b016a2 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html @@ -2,7 +2,7 @@ -performance.Descriptions-20260626-135225 +performance.Descriptions-20260629-200911