Skip to content

Optimize HttpDateParser.TryStringToDate - #34860

Merged
stephentoub merged 2 commits into
dotnet:masterfrom
stephentoub:httpdateparse
Apr 12, 2020
Merged

stephentoub merged 2 commits into
dotnet:masterfrom
stephentoub:httpdateparse

Conversation

@stephentoub

Copy link
Copy Markdown
Member

When HttpResponseMessage headers are enumerated, even though SocketsHttpHandler adds headers with TryAddWithoutValidation, the enumeration ends up validating them (that's something to be discussed and follow-up on separately). As part of that, it validates the Date header that's required of most responses. It does so using DateTimeOffset.TryParseExact, but using a long list of allowed formats as well as options that knock TryParseExact's processing off the fast path. Since most responses are going to contain a date using RFC1123 format (aka "r"), we just try that first, in a way that will generally result in hitting the optimized "r" code path which is much faster.

Method Job Toolchain Mean Error StdDev Ratio RatioSD Gen 0 Gen 1 Gen 2 Allocated
DatePreferred Job-TUINSB \master\corerun.exe 1,534.1 ns 28.19 ns 34.62 ns 1.00 0.00 0.0877 - - 552 B
DatePreferred Job-HCLEYD \pr\corerun.exe 279.2 ns 4.09 ns 3.62 ns 0.18 0.00 0.0825 - - 520 B
DateAsctime Job-TUINSB \master\corerun.exe 5,936.1 ns 118.33 ns 110.68 ns 1.00 0.00 0.0763 - - 520 B
DateAsctime Job-HCLEYD \pr\corerun.exe 5,628.2 ns 110.32 ns 97.80 ns 0.95 0.03 0.0763 - - 520 B
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
using System.Net.Http;

[MemoryDiagnoser]
public class Program
{
    static void Main(string[] args) => BenchmarkSwitcher.FromAssemblies(new[] { typeof(Program).Assembly }).Run(args);

    [Benchmark]
    public DateTimeOffset? DatePreferred()
    {
        var m = new HttpResponseMessage();
        m.Headers.TryAddWithoutValidation("Date", "Sun, 06 Nov 1994 08:49:37 GMT");
        return m.Headers.Date;
    }

    [Benchmark]
    public DateTimeOffset? DateAsctime()
    {
        var m = new HttpResponseMessage();
        m.Headers.TryAddWithoutValidation("Date", "Sun Nov  6 08:49:37 1994");
        return m.Headers.Date;
    }
}

cc: @davidsh, @scalablecory

When HttpResponseMessage headers are enumerated, even though SocketsHttpHandler adds headers with TryAddWithoutValidation, the enumeration ends up validating them (that's something to be discussed and follow-up on separately).  As part of that, it validates the Date header that's required of most responses. It does so using DateTimeOffset.TryParseExact, but using a long list of allowed formats as well as options that knock TryParseExact's processing off the fast path.  Since most responses are going to contain a date using RFC1123 format (aka "r"), we just try that first, in a way that will generally result in hitting the optimized "r" code path which is much faster.
@ghost

ghost commented Apr 12, 2020

Copy link
Copy Markdown

Tagging @dotnet/ncl as an area owner. If you would like to be tagged for a label, please notify danmosemsft.

@davidsh davidsh added this to the 5.0 milestone Apr 12, 2020
Comment thread src/libraries/Common/src/System/Net/HttpDateParser.cs Outdated
Comment thread src/libraries/Common/src/System/Net/HttpDateParser.cs Outdated
@stephentoub
stephentoub merged commit 75efecb into dotnet:master Apr 12, 2020
@stephentoub
stephentoub deleted the httpdateparse branch April 12, 2020 12:12
@stephentoub stephentoub added the tenet-performance Performance related issue label Apr 15, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants