Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Optimize recursion of System.Net.Http.HttpRuleParser.GetExpressionLength #35959

Merged
merged 3 commits into from
Mar 14, 2019
Merged

Optimize recursion of System.Net.Http.HttpRuleParser.GetExpressionLength #35959

merged 3 commits into from
Mar 14, 2019

Conversation

MarcoRossignoli
Copy link
Member

Fixing past bug I found a unuseful ref param passed to GetQuotedStringLength used by GetCommentLength/GetQuotedStringLength parser.
I tried to remove ref to improve performance thank's to less dereferencing and better usage of registers.
I wrote a test

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using System.Collections.Generic;
using System.Net.Http;

namespace HttpRulerParser
{
    [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
    [CategoriesColumn]
    public class HttpRuleParserComment
    {
        [Params(100)]
        public int Count { get; set; }

        public IEnumerable<string> Comments => new[]
        {
            "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/7.0)",
            "((comment)(comment(comment)))"
        };


        public IEnumerable<string> QuotedStrings => new[]
        {
            "token \"quoted string\" token",
            "\"a\\ü\\\"b\\\"c\\\"\\\"d\\\"\""
        };

        [BenchmarkCategory("Comment"), Benchmark(Baseline = true)]
        [ArgumentsSource(nameof(Comments))]
        public void GetCommentLength_Old(string comment)
        {
            for (int i = 0; i < Count; i++)
            {
                HttpRuleParserOld.GetCommentLength(comment, 0, out int len);
            }
        }

        [BenchmarkCategory("Comment"), Benchmark()]
        [ArgumentsSource(nameof(Comments))]
        public void GetCommentLength_New(string comment)
        {
            for (int i = 0; i < Count; i++)
            {
                HttpRuleParserNew.GetCommentLength(comment, 0, out int len);
            }
        }

        [BenchmarkCategory("Quoted"), Benchmark(Baseline = true)]
        [ArgumentsSource(nameof(QuotedStrings))]
        public void GetQuotedStringLength_Old(string quotedString)
        {
            for (int i = 0; i < Count; i++)
            {
                HttpRuleParserOld.GetQuotedStringLength(quotedString, 0, out int len);
            }
        }

        [BenchmarkCategory("Quoted"), Benchmark()]
        [ArgumentsSource(nameof(QuotedStrings))]
        public void GetQuotedStringLength_New(string quotedString)
        {
            for (int i = 0; i < Count; i++)
            {
                HttpRuleParserNew.GetQuotedStringLength(quotedString, 0, out int len);
            }
        }
    }
}

Results

BenchmarkDotNet=v0.11.4, OS=Windows 10.0.17134.590 (1803/April2018Update/Redstone4)
Intel Core i7 CPU 860 2.80GHz (Nehalem), 1 CPU, 8 logical and 4 physical cores
Frequency=2727538 Hz, Resolution=366.6310 ns, Timer=TSC
.NET Core SDK=3.0.100-preview3-010431
  [Host]     : .NET Core 3.0.0-preview3-27503-5 (CoreCLR 4.6.27422.72, CoreFX 4.7.19.12807), 64bit RyuJIT
  DefaultJob : .NET Core 3.0.0-preview3-27503-5 (CoreCLR 4.6.27422.72, CoreFX 4.7.19.12807), 64bit RyuJIT

Method Categories Count quotedString comment Mean Error StdDev Ratio RatioSD
GetQuotedStringLength_Old Quoted 100 "a\ü&quot;b&quot;c&quot;&quot;d&quot;" ? 9,284.0 ns 179.270 ns 257.103 ns 1.00 0.00
GetQuotedStringLength_New Quoted 100 "a\ü&quot;b&quot;c&quot;&quot;d&quot;" ? 8,387.3 ns 166.098 ns 197.728 ns 0.90 0.03
GetCommentLength_Old Comment 100 ? ((com(...)nt))) [29] 26,042.2 ns 158.638 ns 148.390 ns 1.00 0.00
GetCommentLength_New Comment 100 ? ((com(...)nt))) [29] 22,839.2 ns 84.810 ns 70.820 ns 0.88 0.01
GetCommentLength_Old Comment 100 ? Mozil(...)/7.0) [63] 1,384.1 ns 24.599 ns 20.541 ns 1.00 0.00
GetCommentLength_New Comment 100 ? Mozil(...)/7.0) [63] 635.6 ns 9.051 ns 8.467 ns 0.46 0.01
GetQuotedStringLength_Old Quoted 100 token(...)token [27] ? 1,402.8 ns 19.091 ns 17.858 ns 1.00 0.00
GetQuotedStringLength_New Quoted 100 token(...)token [27] ? 626.6 ns 3.480 ns 2.906 ns 0.45 0.01

/cc @davidsh @geoffkizer @stephentoub

@davidsh davidsh added this to the 3.0 milestone Mar 11, 2019
@MarcoRossignoli
Copy link
Member Author

/azp run corefx-outerloop-windows

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-outerloop-linux

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-outerloop-osx

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-outerloop-windows

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-outerloop-linux

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-outerloop-osx

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-outerloop-windows

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

2 similar comments
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-ci (macOS x64_Debug)

@azure-pipelines
Copy link

No pipelines are associated with this pull request.

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-ci

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MarcoRossignoli
Copy link
Member Author

@safern I tried to re-run CI because one leg fail(corefx-ci (macOS x64_Debug))...but seems that failed leg doesn't run, what I'm missing?

@MarcoRossignoli
Copy link
Member Author

@stephentoub PTAL

@safern
Copy link
Member

safern commented Mar 12, 2019

@safern I tried to re-run CI because one leg fail(corefx-ci (macOS x64_Debug))...but seems that failed leg doesn't run, what I'm missing?

Running an individual leg through comment is not yet supported. We've requested this feature. I added it under the known issues section in the docs so that I submit a PR to update it whenever it is enabled:

https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/pullrequest-builds.md#known-issues -- number 7

@MarcoRossignoli
Copy link
Member Author

MarcoRossignoli commented Mar 13, 2019

@safern you're right I know about doc but I was convinced that I already have, in my dreams maybe 😄 , thank's for the answer.

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-outerloop-windows

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-outerloop-windows

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MarcoRossignoli
Copy link
Member Author

/azp run corefx-outerloop-windows

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@davidsh
Copy link
Contributor

davidsh commented Mar 14, 2019

/azp run corefx-outerloop-windows

@davidsh
Copy link
Contributor

davidsh commented Mar 14, 2019

/azp run corefx-outerloop-linux

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@davidsh
Copy link
Contributor

davidsh commented Mar 14, 2019

/azp run corefx-outerloop-osx

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

1 similar comment
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@davidsh davidsh merged commit 4636de3 into dotnet:master Mar 14, 2019
@MarcoRossignoli MarcoRossignoli deleted the getexpressionlengthoptimization branch March 14, 2019 18:35
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…gth (dotnet/corefx#35959)

Optimize recursion of System.Net.Http.HttpRuleParser.GetExpressionLength


Commit migrated from dotnet/corefx@4636de3
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants