-
Notifications
You must be signed in to change notification settings - Fork 272
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
Add BinaryWriter perf tests #1639
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using BenchmarkDotNet.Attributes; | ||
using MicroBenchmarks; | ||
|
||
namespace System.IO.Tests | ||
{ | ||
[BenchmarkCategory(Categories.Libraries)] | ||
public class BinaryWriterExtendedTests | ||
{ | ||
private string _input; | ||
private char[] _inputAsChars; | ||
private BinaryWriter _bw; | ||
|
||
[Params(4, 16, 512, 10_000, 100_000, 500_000, 2_000_000)] | ||
public int StringLengthInChars; | ||
|
||
[GlobalSetup] | ||
public void Setup() | ||
{ | ||
_bw = new BinaryWriter(new NullWriteStream()); | ||
|
||
_input = new string('x', StringLengthInChars); | ||
_inputAsChars = _input.ToCharArray(); | ||
} | ||
|
||
[Benchmark] | ||
public void WriteAsciiCharArray() | ||
{ | ||
_bw.Write(_inputAsChars); | ||
} | ||
|
||
[Benchmark] | ||
public void WriteAsciiString() | ||
{ | ||
_bw.Write(_input); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using BenchmarkDotNet.Attributes; | ||
using MicroBenchmarks; | ||
|
||
namespace System.IO.Tests | ||
{ | ||
[BenchmarkCategory(Categories.Libraries)] | ||
public class BinaryWriterTests | ||
{ | ||
private BinaryWriter _bw; | ||
|
||
[GlobalSetup] | ||
public void Setup() | ||
{ | ||
_bw = new BinaryWriter(new NullWriteStream()); | ||
} | ||
|
||
[Benchmark] | ||
public BinaryWriter DefaultCtor() => new BinaryWriter(Stream.Null); | ||
|
||
[Benchmark] | ||
public void WriteBool() | ||
{ | ||
_bw.Write(true); | ||
} | ||
|
||
[Benchmark] | ||
public void WriteAsciiChar() | ||
{ | ||
_bw.Write('a'); | ||
} | ||
|
||
[Benchmark] | ||
public void WriteNonAsciiChar() | ||
{ | ||
_bw.Write('\u00E0'); | ||
} | ||
|
||
[Benchmark] | ||
public void WriteUInt16() | ||
{ | ||
_bw.Write((ushort)0xabcd); | ||
} | ||
|
||
[Benchmark] | ||
public void WriteUInt32() | ||
{ | ||
_bw.Write((uint)0xdeadbeef); | ||
} | ||
|
||
[Benchmark] | ||
public void WriteUInt64() | ||
{ | ||
_bw.Write((ulong)0xdeadbeef_aabbccdd); | ||
} | ||
|
||
[Benchmark] | ||
public void WriteSingle() | ||
{ | ||
_bw.Write((float)Math.PI); | ||
} | ||
|
||
[Benchmark] | ||
public void WriteDouble() | ||
{ | ||
_bw.Write((double)Math.PI); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace System.IO.Tests | ||
{ | ||
/// <summary> | ||
/// A <see cref="Stream"/> that acts as a null sink for data. Overrides members that | ||
/// <see cref="Stream.Null"/> does not. Used for benchmarking wrappers around Stream | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thank you for adding a clear explanation why |
||
/// without benchmarking the implementation of the inner Stream itself. | ||
/// </summary> | ||
internal sealed class NullWriteStream : Stream | ||
{ | ||
public override bool CanRead => false; | ||
|
||
public override bool CanSeek => false; | ||
|
||
public override bool CanWrite => true; | ||
|
||
public override long Length => throw new NotSupportedException(); | ||
|
||
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } | ||
|
||
public override void Flush() { } | ||
|
||
public override int Read(byte[] buffer, int offset, int count) | ||
{ | ||
throw new NotSupportedException(); | ||
} | ||
|
||
public override long Seek(long offset, SeekOrigin origin) | ||
{ | ||
throw new NotSupportedException(); | ||
} | ||
|
||
public override void SetLength(long value) | ||
{ | ||
throw new NotSupportedException(); | ||
} | ||
GrabYourPitchforks marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public override void Write(byte[] buffer, int offset, int count) { } | ||
|
||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) | ||
{ | ||
return Task.CompletedTask; | ||
} | ||
|
||
public override void WriteByte(byte value) { } | ||
|
||
#if NETCOREAPP2_1_OR_GREATER // these virtual methods only exist in .NET Core 2.1+ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is something new to me. Are you sure that it works outside of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @terrajobst Aren't these defines part of the latest compilers? In theory they should work in any project type in any repo, even non-MSFT code. |
||
public override void Write(ReadOnlySpan<byte> buffer) { } | ||
|
||
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default) | ||
{ | ||
return ValueTask.CompletedTask; | ||
} | ||
#endif | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we reduce the number of test cases to the number of different code paths? https://github.com/dotnet/performance/blob/master/docs/microbenchmark-design-guidelines.md#Code-Paths
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, there should be 3 different code paths. How about 32 chars, 8k chars, and 2M chars?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍