Improve HeaderSplit perf (#9309)
This commit is contained in:
parent
6aee83d8f0
commit
022e79cf17
|
|
@ -19,11 +19,9 @@ namespace Microsoft.AspNetCore.Http.Internal
|
||||||
public static StringValues GetHeaderSplit(IHeaderDictionary headers, string key)
|
public static StringValues GetHeaderSplit(IHeaderDictionary headers, string key)
|
||||||
{
|
{
|
||||||
var values = GetHeaderUnmodified(headers, key);
|
var values = GetHeaderUnmodified(headers, key);
|
||||||
return new StringValues(GetHeaderSplitImplementation(values).ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<string> GetHeaderSplitImplementation(StringValues values)
|
StringValues result = default;
|
||||||
{
|
|
||||||
foreach (var segment in new HeaderSegmentCollection(values))
|
foreach (var segment in new HeaderSegmentCollection(values))
|
||||||
{
|
{
|
||||||
if (!StringSegment.IsNullOrEmpty(segment.Data))
|
if (!StringSegment.IsNullOrEmpty(segment.Data))
|
||||||
|
|
@ -31,10 +29,12 @@ namespace Microsoft.AspNetCore.Http.Internal
|
||||||
var value = DeQuote(segment.Data.Value);
|
var value = DeQuote(segment.Data.Value);
|
||||||
if (!string.IsNullOrEmpty(value))
|
if (!string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
yield return value;
|
result = StringValues.Concat(in result, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StringValues GetHeaderUnmodified(IHeaderDictionary headers, string key)
|
public static StringValues GetHeaderUnmodified(IHeaderDictionary headers, string key)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
[assembly: BenchmarkDotNet.Attributes.AspNetCoreBenchmark]
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
|
using Microsoft.AspNetCore.Http.Internal;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Http.Abstractions.Microbenchmarks
|
||||||
|
{
|
||||||
|
public class GetHeaderSplitBenchmark
|
||||||
|
{
|
||||||
|
HeaderDictionary _dictionary;
|
||||||
|
|
||||||
|
[GlobalSetup]
|
||||||
|
public void GlobalSetup()
|
||||||
|
{
|
||||||
|
var dict = new Dictionary<string, StringValues>()
|
||||||
|
{
|
||||||
|
{ "singleValue", new StringValues("single") },
|
||||||
|
{ "singleValueQuoted", new StringValues("\"single\"") },
|
||||||
|
{ "doubleValue", new StringValues(new [] { "first", "second" }) },
|
||||||
|
{ "manyValue", new StringValues(new [] { "first", "second", "third", "fourth", "fifth", "sixth" }) }
|
||||||
|
};
|
||||||
|
_dictionary = new HeaderDictionary(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void SplitSingleHeader()
|
||||||
|
{
|
||||||
|
var values = ParsingHelpers.GetHeaderSplit(_dictionary, "singleValue");
|
||||||
|
if (values.Count != 1)
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void SplitSingleQuotedHeader()
|
||||||
|
{
|
||||||
|
var values = ParsingHelpers.GetHeaderSplit(_dictionary, "singleValueQuoted");
|
||||||
|
if (values.Count != 1)
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void SplitDoubleHeader()
|
||||||
|
{
|
||||||
|
var values = ParsingHelpers.GetHeaderSplit(_dictionary, "doubleValue");
|
||||||
|
if (values.Count != 2)
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void SplitManyHeaders()
|
||||||
|
{
|
||||||
|
var values = ParsingHelpers.GetHeaderSplit(_dictionary, "manyValue");
|
||||||
|
if (values.Count != 6)
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="BenchmarkDotNet" />
|
||||||
|
<Reference Include="Microsoft.AspNetCore.BenchmarkRunner.Sources" />
|
||||||
|
<Reference Include="Microsoft.AspNetCore.Http.Abstractions" />
|
||||||
|
<Reference Include="Microsoft.AspNetCore.Http" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
Loading…
Reference in New Issue