diff --git a/src/benchmarks/corefx/CommonUtils/PerfUtils.cs b/src/benchmarks/corefx/CommonUtils/PerfUtils.cs index 424b6bf49d3..e4b3aa2fb6e 100644 --- a/src/benchmarks/corefx/CommonUtils/PerfUtils.cs +++ b/src/benchmarks/corefx/CommonUtils/PerfUtils.cs @@ -7,13 +7,13 @@ namespace System { - public class PerfUtils + public static class PerfUtils { /// /// Helper method to create a string containing a number of /// characters equal to the specified length /// - public string CreateString(int length) + public static string CreateString(int length) { char[] str = new char[length]; diff --git a/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Convert.cs b/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Convert.cs new file mode 100644 index 00000000000..d73c1704564 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Convert.cs @@ -0,0 +1,64 @@ +// 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 Benchmarks; + +namespace System +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Convert + { + private static byte[] InitializeBinaryDataCollection(int size) + { + var random = new Random(30000); + byte[] binaryData = new byte[size]; + random.NextBytes(binaryData); + + return binaryData; + } + + private const int Size = 1024; + + private object _stringValue = "Hello World!"; + private object _intValue = 1000; + private byte[] _binaryData = InitializeBinaryDataCollection(Size); + private char[] _base64CharArray; + + [Benchmark] + public TypeCode GetTypeCode() => Convert.GetTypeCode(_stringValue); + + [Benchmark] + public object ChangeType() => Convert.ChangeType(_intValue, typeof(string)); + + [GlobalSetup(Target = nameof(ToBase64CharArray))] + public void SetupToBase64CharArray() + { + int insertLineBreaksArraySize = Convert.ToBase64String(_binaryData, Base64FormattingOptions.InsertLineBreaks).Length; + int noneArraySize = Convert.ToBase64String(_binaryData, Base64FormattingOptions.None).Length; + _base64CharArray = new char[Math.Max(noneArraySize, insertLineBreaksArraySize)]; + } + + [Benchmark] + [Arguments(Size, Base64FormattingOptions.InsertLineBreaks)] + [Arguments(Size, Base64FormattingOptions.None)] + public int ToBase64CharArray(int binaryDataSize, Base64FormattingOptions formattingOptions) + => Convert.ToBase64CharArray(_binaryData, 0, binaryDataSize, _base64CharArray, 0, formattingOptions); + + [Benchmark] + [Arguments(Base64FormattingOptions.InsertLineBreaks)] + [Arguments(Base64FormattingOptions.None)] + public string ToBase64String(Base64FormattingOptions formattingOptions) + => Convert.ToBase64String(_binaryData, formattingOptions); + + [Benchmark] + [Arguments("Fri, 27 Feb 2009 03:11:21 GMT")] + [Arguments("Thursday, February 26, 2009")] + [Arguments("February 26, 2009")] + [Arguments("12/12/1999 11:59:59 PM")] + [Arguments("12/12/1999")] + public DateTime ToDateTime_String(string value) + => Convert.ToDateTime(value); + } +} diff --git a/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Environment.cs b/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Environment.cs new file mode 100644 index 00000000000..805d4a051a9 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Environment.cs @@ -0,0 +1,40 @@ +// 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.Collections; +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Environment + { + private const string Key = "7efd538f-dcab-4806-839a-972bc463a90c"; + private const string ExpandedKey = "%" + Key + "%"; + + [GlobalSetup] + public void Setup() => Environment.SetEnvironmentVariable(Key, "value"); + + [GlobalCleanup] + public void Cleanup() => Environment.SetEnvironmentVariable(Key, null); + + [Benchmark] + public string GetEnvironmentVariable() => Environment.GetEnvironmentVariable(Key); + + [Benchmark] + public string ExpandEnvironmentVariables() => Environment.ExpandEnvironmentVariables(ExpandedKey); + + [Benchmark] + public IDictionary GetEnvironmentVariables() => Environment.GetEnvironmentVariables(); + + [Benchmark] + [Arguments(Environment.SpecialFolder.System, Environment.SpecialFolderOption.None)] + public void GetFolderPath(Environment.SpecialFolder folder, Environment.SpecialFolderOption option) + => Environment.GetFolderPath(folder, option); + + [Benchmark] + public string[] GetLogicalDrives() => Environment.GetLogicalDrives(); + } +} diff --git a/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Path.cs b/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Path.cs new file mode 100644 index 00000000000..7f7c3ae6bc8 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Path.cs @@ -0,0 +1,61 @@ +// 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 Benchmarks; + +namespace System.IO.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Path + { + private readonly string _testPath = FileUtils.GetTestFilePath(); + private readonly string _testPath10 = PerfUtils.CreateString(10); + private readonly string _testPath200 = PerfUtils.CreateString(200); + private readonly string _testPath500 = PerfUtils.CreateString(500); + private readonly string _testPath1000 = PerfUtils.CreateString(1000); + + [Benchmark] + public string Combine() => Path.Combine(_testPath, _testPath10); + + [Benchmark] + public string GetFileName() => Path.GetFileName(_testPath); + + [Benchmark] + public string GetDirectoryName() => Path.GetDirectoryName(_testPath); + + [Benchmark] + public string ChangeExtension() => Path.ChangeExtension(_testPath, ".new"); + + [Benchmark] + public string GetExtension() => Path.GetExtension(_testPath); + + [Benchmark] + public string GetFileNameWithoutExtension() => Path.GetFileNameWithoutExtension(_testPath); + + [Benchmark] + public string GetFullPathForLegacyLength() => Path.GetFullPath(_testPath200); + + [Benchmark] + public string GetFullPathForTypicalLongPath() => Path.GetFullPath(_testPath500); + + [Benchmark] + public void GetFullPathForReallyLongPath() => Path.GetFullPath(_testPath1000); + + [Benchmark] + public string GetPathRoot() => Path.GetPathRoot(_testPath); + + [Benchmark] + public string GetRandomFileName() => Path.GetRandomFileName(); + + [Benchmark] + public string GetTempPath() => Path.GetTempPath(); + + [Benchmark] + public bool HasExtension() => Path.HasExtension(_testPath); + + [Benchmark] + public bool IsPathRooted() => Path.IsPathRooted(_testPath); + } +} diff --git a/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Random.cs b/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Random.cs new file mode 100644 index 00000000000..a3dfddf6360 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime.Extensions/Perf.Random.cs @@ -0,0 +1,31 @@ +// 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 Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Random + { + Random _random = new Random(123456); + byte[] _bytes = new byte[1000]; + + [Benchmark] + public Random ctor() => new Random(); + + [Benchmark] + public int Next_int() => _random.Next(10000); + + [Benchmark] + public int Next_int_int() => _random.Next(100, 10000); + + [Benchmark] + public void NextBytes() => _random.NextBytes(_bytes); + + [Benchmark] + public double NextDouble() => _random.NextDouble(); + } +} diff --git a/src/benchmarks/corefx/System.Runtime.Extensions/Perf.StreamWriter.cs b/src/benchmarks/corefx/System.Runtime.Extensions/Perf.StreamWriter.cs new file mode 100644 index 00000000000..1012bd88f05 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime.Extensions/Perf.StreamWriter.cs @@ -0,0 +1,111 @@ +// 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.Collections.Generic; +using System.Text; +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.IO.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_StreamWriter + { + private const int MemoryStreamSize = 32768; + private const int TotalWriteCount = 16777216; // 2^24 - should yield around 300ms runs + private const int DefaultStreamWriterBufferSize = 1024; // Same as StreamWriter internal default + + private string _string2 = new string('a', 2), _string100 = new string('a', 100); + private char[] _buffer2 = new string('a', 2).ToCharArray(), _buffer100 = new string('a', 100).ToCharArray(); + private char[] _buffer12 = new string('a', 12).ToCharArray(), _buffer110 = new string('a', 110).ToCharArray(); + private MemoryStream _memoryStream; + private StreamWriter _streamWriter; + + public IEnumerable WriteLengthMemberData() + { + yield return 2; + yield return 100; + } + + [GlobalSetup] + public void Setup() + { + _memoryStream = new MemoryStream(MemoryStreamSize); + _streamWriter = new StreamWriter(_memoryStream, new UTF8Encoding(false, true), DefaultStreamWriterBufferSize, leaveOpen: true); + } + + [GlobalCleanup] + public void Cleanup() + { + _memoryStream.Dispose(); + _streamWriter.Dispose(); + } + + [Benchmark] + [ArgumentsSource(nameof(WriteLengthMemberData))] + public void WriteCharArray(int writeLength) + { + char[] buffer = writeLength == 2 ? _buffer2 : _buffer100; + int innerIterations = MemoryStreamSize / writeLength; + int outerIteration = TotalWriteCount / innerIterations; + + var writer = _streamWriter; + var stream = _memoryStream; + + for (int i = 0; i < outerIteration; i++) + { + for (int j = 0; j < innerIterations; j++) + { + writer.Write(buffer); + } + writer.Flush(); + stream.Position = 0; + } + } + + [Benchmark] + [ArgumentsSource(nameof(WriteLengthMemberData))] + public void WritePartialCharArray(int writeLength) + { + char[] buffer = writeLength == 2 ? _buffer12 : _buffer110; + int innerIterations = MemoryStreamSize / writeLength; + int outerIteration = TotalWriteCount / innerIterations; + + var writer = _streamWriter; + var stream = _memoryStream; + + for (int i = 0; i < outerIteration; i++) + { + for (int j = 0; j < innerIterations; j++) + { + writer.Write(buffer, 10, writeLength); + } + writer.Flush(); + stream.Position = 0; + } + } + + [Benchmark] + [ArgumentsSource(nameof(WriteLengthMemberData))] + public void WriteString(int writeLength) + { + string value = writeLength == 2 ? _string2 : _string100; + int innerIterations = MemoryStreamSize / writeLength; + int outerIteration = TotalWriteCount / innerIterations; + + var writer = _streamWriter; + var stream = _memoryStream; + + for (int i = 0; i < outerIteration; i++) + { + for (int j = 0; j < innerIterations; j++) + { + writer.Write(value); + } + writer.Flush(); + stream.Position = 0; + } + } + } +} diff --git a/src/benchmarks/corefx/System.Text.Encoding/Perf.Encoding.cs b/src/benchmarks/corefx/System.Text.Encoding/Perf.Encoding.cs index 125a623a932..b886c948a01 100644 --- a/src/benchmarks/corefx/System.Text.Encoding/Perf.Encoding.cs +++ b/src/benchmarks/corefx/System.Text.Encoding/Perf.Encoding.cs @@ -14,8 +14,6 @@ public class Perf_Encoding [Params("utf-8", "ascii")] public string encName; // the field must be called length (starts with lowercase) to keep old benchmark id in BenchView, do NOT change it - private readonly PerfUtils _utils = new PerfUtils(); - private Encoding _enc; private string _toEncode; private byte[] _bytes; @@ -25,7 +23,7 @@ public class Perf_Encoding public void SetupGetBytes() { _enc = Encoding.GetEncoding(encName); - _toEncode = _utils.CreateString(size); + _toEncode = PerfUtils.CreateString(size); } [Benchmark] @@ -50,7 +48,7 @@ public byte[] GetBytes() public void SetupGetStringAndGetChars() { _enc = Encoding.GetEncoding(encName); - _bytes = _enc.GetBytes(_utils.CreateString(size));; + _bytes = _enc.GetBytes(PerfUtils.CreateString(size));; } [Benchmark] @@ -113,7 +111,7 @@ public Encoder GetEncoder() public void SetupGetByteCount() { _enc = Encoding.GetEncoding(encName); - _chars = _utils.CreateString(size).ToCharArray(); + _chars = PerfUtils.CreateString(size).ToCharArray(); } [Benchmark]