Skip to content

Commit ae6e1d0

Browse files
Si13n7Si13n7
authored andcommitted
Add benchmark test cases
1 parent 18fe802 commit ae6e1d0

File tree

10 files changed

+135
-13
lines changed

10 files changed

+135
-13
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#if NET5_0_OR_GREATER && RELEASE
2+
namespace Roydl.Text.Test.BenchmarkTests
3+
{
4+
using System;
5+
using System.Collections.Concurrent;
6+
using System.Globalization;
7+
using System.IO;
8+
using System.Linq;
9+
using System.Threading.Tasks;
10+
using BinaryToText;
11+
using NUnit.Framework;
12+
13+
[TestFixture]
14+
[NonParallelizable]
15+
[Platform(Include = TestVars.PlatformCross)]
16+
[Category("Performance")]
17+
public class BinToTextPerformanceTests
18+
{
19+
private const int BenchmarkRepeats = 20;
20+
21+
private static readonly TestCaseData[] BenchmarkTestData =
22+
{
23+
new(BinToTextEncoding.Base02, 65536),
24+
new(BinToTextEncoding.Base08, 65536),
25+
new(BinToTextEncoding.Base10, 65536),
26+
new(BinToTextEncoding.Base16, 65536),
27+
new(BinToTextEncoding.Base32, 65536),
28+
new(BinToTextEncoding.Base64, 65536),
29+
new(BinToTextEncoding.Base85, 65536),
30+
new(BinToTextEncoding.Base91, 65536)
31+
};
32+
33+
private static readonly ConcurrentDictionary<string, ConcurrentBag<double>> BenchmarkResults = new(Environment.ProcessorCount, BenchmarkTestData.Length);
34+
35+
[OneTimeTearDown]
36+
[SetCulture("en-US")]
37+
public void CreateResultFiles()
38+
{
39+
if (!BenchmarkResults.Any())
40+
return;
41+
var dir = TestContext.CurrentContext.TestDirectory;
42+
Parallel.ForEach(BenchmarkResults, pair =>
43+
{
44+
var (key, value) = pair;
45+
var file = Path.Combine(dir, $"__Benchmark-{string.Concat(key.Split(Path.GetInvalidFileNameChars()))}.txt");
46+
var sorted = value.OrderByDescending(x => x).ToArray();
47+
var digits = BenchmarkRepeats.ToString(NumberFormatInfo.InvariantInfo).Length;
48+
var content =
49+
$"Average: {sorted.Sum() / sorted.Length:0.0,6} MiB/s" +
50+
Environment.NewLine +
51+
$" Best: {sorted[0]:0.0,6} MiB/s" +
52+
Environment.NewLine +
53+
$" Worst: {sorted[^1]:0.0,6} MiB/s" +
54+
Environment.NewLine +
55+
Environment.NewLine +
56+
$"Results of {sorted.Length} runs with a total duration of {sorted.Length * 9} seconds:" +
57+
Environment.NewLine +
58+
string.Join(Environment.NewLine, sorted.Select((x, i) => $"{(i + 1).ToString().PadLeft(digits)}: {x:0.0,6} MiB/s"));
59+
File.WriteAllText(file, content);
60+
});
61+
}
62+
63+
private static void RunBenchmark(BinToTextEncoding algorithm, int packetSize, bool saveResults)
64+
{
65+
var inst = algorithm.GetDefaultInstance();
66+
var data = new byte[packetSize];
67+
TestVars.Randomizer.NextBytes(data);
68+
69+
const int cycles = 9 / 3;
70+
var sw = TestVars.StopWatch;
71+
var rate = 0d;
72+
for (var i = 0; i < cycles; i++)
73+
{
74+
var total = 0L;
75+
sw.Restart();
76+
while (sw.Elapsed < TimeSpan.FromSeconds(cycles))
77+
{
78+
inst.EncodeBytes(data);
79+
total += data.Length;
80+
}
81+
sw.Stop();
82+
rate = Math.Max(total / sw.Elapsed.TotalSeconds / 1024 / 1024, rate);
83+
}
84+
85+
if (!saveResults)
86+
{
87+
TestContext.Write(@" {0} Benchmark - Throughput: '{1:0.0} MiB/s'; ", algorithm, rate);
88+
switch (packetSize)
89+
{
90+
case > 1024:
91+
TestContext.Write(@"Packet Size: '{0:0} KiB';", packetSize / 1024);
92+
break;
93+
default:
94+
TestContext.Write(@"Packet Size: '{0:0} Bytes';", packetSize);
95+
break;
96+
}
97+
return;
98+
}
99+
100+
var key = $"{algorithm}@{packetSize}";
101+
if (!BenchmarkResults.ContainsKey(key))
102+
BenchmarkResults[key] = new ConcurrentBag<double>();
103+
BenchmarkResults[key].Add(rate);
104+
}
105+
106+
[Test]
107+
[TestCaseSource(nameof(BenchmarkTestData))]
108+
public void BenchmarkOnce(BinToTextEncoding algorithm, int dataSize) =>
109+
RunBenchmark(algorithm, dataSize, false);
110+
111+
[Explicit]
112+
[Test]
113+
[TestCaseSource(nameof(BenchmarkTestData))]
114+
[Repeat(BenchmarkRepeats)]
115+
public void BenchmarkRepeat(BinToTextEncoding algorithm, int dataSize) =>
116+
RunBenchmark(algorithm, dataSize, true);
117+
}
118+
}
119+
#endif

test/BinaryToTextTests/Base02Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[TestFixture]
1010
[Parallelizable]
11-
[Platform(Include = TestVars.PlatformInclude)]
11+
[Platform(Include = TestVars.PlatformCross)]
1212
public class Base02Tests
1313
{
1414
private const BinToTextEncoding Algorithm = BinToTextEncoding.Base02;

test/BinaryToTextTests/Base08Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[TestFixture]
1010
[Parallelizable]
11-
[Platform(Include = TestVars.PlatformInclude)]
11+
[Platform(Include = TestVars.PlatformCross)]
1212
public class Base08Tests
1313
{
1414
private const BinToTextEncoding Algorithm = BinToTextEncoding.Base08;

test/BinaryToTextTests/Base10Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[TestFixture]
1010
[Parallelizable]
11-
[Platform(Include = TestVars.PlatformInclude)]
11+
[Platform(Include = TestVars.PlatformCross)]
1212
public class Base10Tests
1313
{
1414
private const BinToTextEncoding Algorithm = BinToTextEncoding.Base10;

test/BinaryToTextTests/Base16Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[TestFixture]
1010
[Parallelizable]
11-
[Platform(Include = TestVars.PlatformInclude)]
11+
[Platform(Include = TestVars.PlatformCross)]
1212
public class Base16Tests
1313
{
1414
private const BinToTextEncoding Algorithm = BinToTextEncoding.Base16;

test/BinaryToTextTests/Base32Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[TestFixture]
1010
[Parallelizable]
11-
[Platform(Include = TestVars.PlatformInclude)]
11+
[Platform(Include = TestVars.PlatformCross)]
1212
public class Base32Tests
1313
{
1414
private const BinToTextEncoding Algorithm = BinToTextEncoding.Base32;

test/BinaryToTextTests/Base64Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[TestFixture]
1010
[Parallelizable]
11-
[Platform(Include = TestVars.PlatformInclude)]
11+
[Platform(Include = TestVars.PlatformCross)]
1212
public class Base64Tests
1313
{
1414
private const BinToTextEncoding Algorithm = BinToTextEncoding.Base64;

test/BinaryToTextTests/Base85Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[TestFixture]
1010
[Parallelizable]
11-
[Platform(Include = TestVars.PlatformInclude)]
11+
[Platform(Include = TestVars.PlatformCross)]
1212
public class Base85Tests
1313
{
1414
private const BinToTextEncoding Algorithm = BinToTextEncoding.Base85;

test/BinaryToTextTests/Base91Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[TestFixture]
1010
[Parallelizable]
11-
[Platform(Include = TestVars.PlatformInclude)]
11+
[Platform(Include = TestVars.PlatformCross)]
1212
public class Base91Tests
1313
{
1414
private const BinToTextEncoding Algorithm = BinToTextEncoding.Base91;

test/TestVars.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
namespace Roydl.Text.Test
22
{
33
using System;
4+
using System.Diagnostics;
45
using System.IO;
56
using System.Linq;
7+
using NUnit.Framework;
68

79
public enum TestVarsType
810
{
@@ -17,14 +19,17 @@ public enum TestVarsType
1719

1820
public static class TestVars
1921
{
20-
public const string PlatformInclude = "Win32NT,Linux";
22+
public const string PlatformCross = "Win32NT,Linux";
2123
public const string QuoteStr = "We know what we are, but know not what we may be.";
2224
public const string TestStr = "Test";
2325
public static readonly byte[] TestBytes = { 0x54, 0x65, 0x73, 0x74 };
24-
private static readonly Random Randomizer = new();
2526

2627
public static string RangeStr { get; } = new(Enumerable.Range(byte.MinValue, byte.MaxValue).Select(i => (char)i).ToArray());
2728

29+
public static Random Randomizer => new();
30+
31+
public static Stopwatch StopWatch => new();
32+
2833
public static byte[] GetRandomBytes(int size = 0)
2934
{
3035
if (size < 1)
@@ -40,9 +45,7 @@ public static byte[] GetRandomBytes(int size = 0)
4045

4146
public static string GetTempFilePath(string name)
4247
{
43-
var dir = Environment.CurrentDirectory;
44-
if (!Directory.Exists(dir)) // broken dir on some test platforms
45-
dir = AppDomain.CurrentDomain.BaseDirectory;
48+
var dir = TestContext.CurrentContext.TestDirectory;
4649
return Path.Combine(dir, $"test-{name}-{Guid.NewGuid()}.tmp");
4750
}
4851
}

0 commit comments

Comments
 (0)