Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(32, 8_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);
}
}
}
72 changes: 72 additions & 0 deletions src/benchmarks/micro/libraries/System.IO/BinaryWriterTests.cs
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);
}
}
}
47 changes: 47 additions & 0 deletions src/benchmarks/micro/libraries/System.IO/NullWriteStream.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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

@adamsitnik adamsitnik Jan 28, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thank you for adding a clear explanation why Stream.Null is not enough 👍

/// 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();

public override void Write(byte[] buffer, int offset, int count) { }

public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => Task.CompletedTask;

public override void WriteByte(byte value) { }

#if NETCOREAPP2_1_OR_GREATER // these virtual methods only exist in .NET Core 2.1+

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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 dotnet/runtime? cc @ViktorHofer

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The 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) => ValueTask.CompletedTask;
#endif
}
}