-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathXmlCommentsBenchmark.cs
More file actions
160 lines (137 loc) · 5.9 KB
/
XmlCommentsBenchmark.cs
File metadata and controls
160 lines (137 loc) · 5.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using System.Reflection;
using System.Xml;
using System.Xml.XPath;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerGen.Test;
using Swashbuckle.AspNetCore.TestSupport;
namespace Swashbuckle.AspNetCore.Benchmarks;
[MemoryDiagnoser]
public class XmlCommentsBenchmark
{
private XmlCommentsDocumentFilter _documentFilter;
private OpenApiDocument _document;
private DocumentFilterContext _documentFilterContext;
private XmlCommentsOperationFilter _operationFilter;
private OpenApiOperation _operation;
private OperationFilterContext _operationFilterContext;
private XmlCommentsParameterFilter _parameterFilter;
private OpenApiParameter _parameter;
private ParameterFilterContext _parameterFilterContext;
private XmlCommentsRequestBodyFilter _requestBodyFilter;
private OpenApiRequestBody _requestBody;
private RequestBodyFilterContext _requestBodyFilterContext;
private const int AddMemberCount = 10_000;
[GlobalSetup]
public void Setup()
{
// Load XML
XmlDocument xmlDocument;
using (var xmlComments = File.OpenText($"{typeof(FakeControllerWithXmlComments).Assembly.GetName().Name}.xml"))
{
xmlDocument = new XmlDocument();
xmlDocument.Load(xmlComments);
}
// Append dummy members to XML document
XPathNavigator navigator = xmlDocument.CreateNavigator()!;
navigator.MoveToRoot();
navigator.MoveToChild("doc", string.Empty);
navigator.MoveToChild("members", string.Empty);
for (int i = 0; i < AddMemberCount; i++)
{
navigator.PrependChild(@$"<member name=""benchmark_{i}""></member>");
}
using var xmlStream = new MemoryStream();
xmlDocument.Save(xmlStream);
xmlStream.Seek(0, SeekOrigin.Begin);
var xPathDocument = new XPathDocument(xmlStream);
var members = XmlCommentsDocumentHelper.CreateMemberDictionary(xPathDocument);
// Document
_document = new OpenApiDocument();
_documentFilterContext = new DocumentFilterContext(
[
new ApiDescription
{
ActionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = typeof(FakeControllerWithXmlComments).GetTypeInfo(),
ControllerName = nameof(FakeControllerWithXmlComments),
},
},
new ApiDescription
{
ActionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = typeof(FakeControllerWithXmlComments).GetTypeInfo(),
ControllerName = nameof(FakeControllerWithXmlComments),
},
},
],
null,
null);
_documentFilter = new XmlCommentsDocumentFilter(members, new());
// Operation
_operation = new OpenApiOperation();
var methodInfo = typeof(FakeConstructedControllerWithXmlComments)
.GetMethod(nameof(FakeConstructedControllerWithXmlComments.ActionWithSummaryAndResponseTags));
var apiDescription = ApiDescriptionFactory.Create(methodInfo: methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource");
_operationFilterContext = new OperationFilterContext(apiDescription, null, null, null, methodInfo);
_operationFilter = new XmlCommentsOperationFilter(members, new());
// Parameter
_parameter = new()
{
Schema = new OpenApiSchema()
{
Type = JsonSchemaTypes.String,
Description = "schema-level description",
},
};
var propertyInfo = typeof(XmlAnnotatedType).GetProperty(nameof(XmlAnnotatedType.StringProperty));
var apiParameterDescription = new ApiParameterDescription();
var xmlDocMembers = XmlCommentsDocumentHelper.CreateMemberDictionary(xPathDocument);
_parameterFilterContext = new ParameterFilterContext(apiParameterDescription, null, null, null, propertyInfo: propertyInfo);
_parameterFilter = new XmlCommentsParameterFilter(xmlDocMembers, new());
// Request Body
_requestBody = new OpenApiRequestBody
{
#if NET11_0_OR_GREATER
Content = new Dictionary<string, IOpenApiMediaType>
#else
Content = new Dictionary<string, OpenApiMediaType>
#endif
{
["application/json"] = new OpenApiMediaType()
{
Schema = new OpenApiSchema()
{
Type = JsonSchemaTypes.String,
},
},
},
};
var parameterInfo = typeof(FakeControllerWithXmlComments)
.GetMethod(nameof(FakeControllerWithXmlComments.ActionWithParamTags))!
.GetParameters()[0];
var bodyParameterDescription = new ApiParameterDescription
{
ParameterDescriptor = new ControllerParameterDescriptor { ParameterInfo = parameterInfo }
};
_requestBodyFilterContext = new RequestBodyFilterContext(bodyParameterDescription, null, null, null, null);
_requestBodyFilter = new XmlCommentsRequestBodyFilter(xmlDocMembers, new());
}
[Benchmark]
public void Document()
=> _documentFilter.Apply(_document, _documentFilterContext);
[Benchmark]
public void Operation()
=> _operationFilter.Apply(_operation, _operationFilterContext);
[Benchmark]
public void Parameter()
=> _parameterFilter.Apply(_parameter, _parameterFilterContext);
[Benchmark]
public void RequestBody()
=> _requestBodyFilter.Apply(_requestBody, _requestBodyFilterContext);
}