Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Override Read(Span)/ReadByte on PipeReaderStream #55086

Merged
merged 1 commit into from
Jul 8, 2021

Conversation

stephentoub
Copy link
Member

We can do better than the base implementations for reading. For writing, there's not a lot we can do better than the base.

Fixes #53692
cc: @halter73

Method Toolchain Mean Ratio Allocated
ReadByte \main\corerun.exe 542,053.1 ns 1.00 131,072 B
ReadByte \pr\corerun.exe 423,396.2 ns 0.78 0 B
ReadSpan \main\corerun.exe 459.7 ns 1.00 72 B
ReadSpan \pr\corerun.exe 309.6 ns 0.67 0 B
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;
using Perfolizer.Horology;
using System;
using System.Globalization;
using System.IO;
using System.IO.Pipelines;

[MemoryDiagnoser]
public class Program
{
    public static void Main(string[] args) =>
        BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args,
            DefaultConfig.Instance.WithSummaryStyle(new SummaryStyle(CultureInfo.InvariantCulture,
                printUnitsInHeader: false, sizeUnit: SizeUnit.B, timeUnit: TimeUnit.Nanosecond, printZeroValuesInContent: true)));

    const int Length = 4096;

    private Stream _writer, _reader;
    private byte[] _buffer = new byte[Length];

    public Program()
    {
        var pipe = new Pipe();
        _writer = pipe.Writer.AsStream();
        _reader = pipe.Reader.AsStream();
    }

    [Benchmark]
    public void ReadByte()
    {
        _writer.WriteAsync(_buffer).GetAwaiter().GetResult();
        for (int i = 0; i < Length; i++)
        {
            _reader.ReadByte();
        }
    }

    [Benchmark]
    public void ReadSpan()
    {
        _writer.WriteAsync(_buffer).GetAwaiter().GetResult();
        Span<byte> buffer = _buffer;
        while (!buffer.IsEmpty)
        {
            buffer = buffer.Slice(_reader.Read(buffer));
        }
    }
}

We can do better than the base implementations for reading.  For writing, there's not a lot we can do better than the base.
@adamsitnik adamsitnik added the tenet-performance Performance related issue label Jul 8, 2021
Copy link
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

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

LGTM, that is a very nice improvement!

@adamsitnik adamsitnik merged commit 1ca17cd into dotnet:main Jul 8, 2021
@adamsitnik adamsitnik added this to the 6.0.0 milestone Jul 8, 2021
@stephentoub stephentoub deleted the pipelinesreadbyte branch July 8, 2021 13:29
@ghost ghost locked as resolved and limited conversation to collaborators Aug 7, 2021
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.

Override more methods in PipeReaderStream and PipeWriterStream
2 participants