Skip to content

Optimize HttpDateParser.TryStringToDate#34860

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

Optimize HttpDateParser.TryStringToDate#34860
stephentoub merged 2 commits intodotnet:masterfrom
stephentoub:httpdateparse

Conversation

@stephentoub
Copy link
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
Copy link

ghost commented Apr 12, 2020

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
@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