Skip to content

Commit

Permalink
refactor: add behcmark object
Browse files Browse the repository at this point in the history
  • Loading branch information
ikpil committed Nov 11, 2023
1 parent 806294b commit eb3cc98
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 98 deletions.
83 changes: 83 additions & 0 deletions src/DotFastLZ.Benchmark/Benchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.Diagnostics;

namespace DotFastLZ.Benchmark;

public static class Benchmarks
{
public static BenchmarkResult Start(string name, string filename, byte[] srcBytes, byte[] dstBytes, Func<byte[], byte[], long> compress, Func<byte[], long, byte[], long> decompress)
{
var result = new BenchmarkResult();
result.Name = name;
result.FileName = filename;
result.SourceByteLength = srcBytes.Length;
result.Compression.ElapsedWatch = new Stopwatch();
result.Compression.ElapsedWatch.Start();
for (int i = 0; i < 5; ++i)
{
long size = compress.Invoke(srcBytes, dstBytes);
result.Compression.InputBytes += result.SourceByteLength;
result.Compression.OutputBytes += size;
result.Times += 1;
}

result.Compression.ElapsedWatch.Stop();

var decompInputLength = result.Compression.OutputBytes / result.Times;
//dstBytes.AsSpan(0, (int)(compressedResult.DestBytes / compressedResult.Times)).CopyTo(srcBytes);

result.Decompression.ElapsedWatch = new Stopwatch();
result.Decompression.ElapsedWatch.Start();
for (int i = 0; i < 5; ++i)
{
long size = decompress.Invoke(dstBytes, decompInputLength, srcBytes);
result.Decompression.InputBytes += decompInputLength;
result.Decompression.OutputBytes += size;
result.Times += 1;
}

result.Decompression.ElapsedWatch.Stop();

//Console.WriteLine(result.ToString());
return result;
}
}

public class Benchmark
{
public virtual string Name => "unknown";

public virtual BenchmarkResult Start(string filename, byte[] srcBytes, byte[] dstBytes)
{
return null;
}
}

public class BenchmarkMemCopy : Benchmark
{
public override string Name => "memcpy";

//var memoryCopy = Benchmark($"memcpy", filename, srcBytes.ToArray(), dstBytes, CompressMemcpy, DecompressMemcpy);

public BenchmarkMemCopy()
{
}

public override BenchmarkResult Start(string filename, byte[] srcBytes, byte[] dstBytes)
{
return Benchmarks.Start(Name, filename, srcBytes, dstBytes, CompressMemcpy, DecompressMemcpy);
}


public static long CompressMemcpy(byte[] srcBytes, byte[] dstBytes)
{
srcBytes.CopyTo(new Span<byte>(dstBytes));
return srcBytes.Length;
}

public static long DecompressMemcpy(byte[] srcBytes, long size, byte[] dstBytes)
{
srcBytes.AsSpan(0, (int)size).CopyTo(new Span<byte>(dstBytes));
return size;
}
}
15 changes: 13 additions & 2 deletions src/DotFastLZ.Benchmark/BenchmarkResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

public class BenchmarkResult
{
public const int CollSize = 4;
public const int CollSize = 6;

public string Name;
public string FileName;
public long SourceByteLength;

public int Times;
public BenchmarkSpeed Compression;
public BenchmarkSpeed Decompression;
Expand All @@ -13,7 +17,8 @@ public override string ToString()
var result = "";
result += $"{Name}\n";
result += $" - times: {Times}\n";
result += $" - source bytes: {Compression.InputBytes / Times}\n";
result += $" - filename : {FileName}\n";
result += $" - source bytes: {ToSourceKbString()} kB/s\n";
result += $" - compression bytes: {Compression.OutputBytes / Times}\n";
result += $" - compression rate: {Compression.ComputeRate():F2}%\n";
result += $" - compression speed: {Compression.ComputeSpeed():F2} MB/s\n";
Expand All @@ -22,6 +27,12 @@ public override string ToString()
return result;
}

public string ToSourceKbString()
{
double mb = (double)SourceByteLength / 1024;
return $"{mb:F2}";
}

public double ComputeTotalSpeed()
{
return Compression.ComputeSpeed() + Decompression.ComputeSpeed();
Expand Down
157 changes: 61 additions & 96 deletions src/DotFastLZ.Benchmark/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ public static void Main(string[] args)
try
{
R.ExtractAll();

var totalResults = new List<BenchmarkResult>();
foreach (var file in R.SourceFiles)
{
var results = BenchmarkFile(file);
Print($"Benchmark : compression {file}", results);
//break;
totalResults.AddRange(results);
}

Print($"Benchmark", totalResults);
}
catch (Exception e)
{
Expand All @@ -35,98 +38,49 @@ public static void Main(string[] args)
}
}

private static List<BenchmarkResult> BenchmarkFile(string file)
private static List<BenchmarkResult> BenchmarkFile(string filename)
{
var results = new List<BenchmarkResult>();

var filepath = R.Find(Path.Combine(R.Prefix, file));
var filepath = R.Find(Path.Combine(R.Prefix, filename));
var srcBytes = R.ToBytes(filepath);
var dstBytes = new byte[srcBytes.Length * 2];

// memcpy
var memoryCopy = Benchmark($"memcpy", srcBytes.ToArray(), dstBytes, CompressMemcpy, DecompressMemcpy);
var benchmark = new BenchmarkMemCopy();
var memoryCopy = benchmark.Start(filename, srcBytes.ToArray(), dstBytes);
results.Add(memoryCopy);

// DotFastLZ fastlz
var fastlzLv1 = Benchmark($"DotFastLZ.Compression L1", srcBytes.ToArray(), dstBytes, CompressDotFastLZL1, DecompressDotFastLZ);
var fastlzLv2 = Benchmark($"DotFastLZ.Compression L2", srcBytes.ToArray(), dstBytes, CompressDotFastLZL2, DecompressDotFastLZ);
results.Add(fastlzLv1);
results.Add(fastlzLv2);

// K4os LZ4
var k4osL01 = Benchmark($"K4os.Compression.LZ4 L00", srcBytes.ToArray(), dstBytes,
(s, d) => CompressK4osLZ4(s, d, LZ4Level.L00_FAST), DecompressK4osLZ4);
var k4osL12 = Benchmark($"K4os.Compression.LZ4 L12", srcBytes.ToArray(), dstBytes,
(s, d) => CompressK4osLZ4(s, d, LZ4Level.L12_MAX), DecompressK4osLZ4);
var k4osL03HC = Benchmark($"K4os.Compression.LZ4 L03_HC", srcBytes.ToArray(), dstBytes,
(s, d) => CompressK4osLZ4(s, d, LZ4Level.L03_HC), DecompressK4osLZ4);
var k4osL09HC = Benchmark($"K4os.Compression.LZ4 L09_HC", srcBytes.ToArray(), dstBytes,
(s, d) => CompressK4osLZ4(s, d, LZ4Level.L09_HC), DecompressK4osLZ4);
results.Add(k4osL01);
results.Add(k4osL12);
results.Add(k4osL03HC);
results.Add(k4osL09HC);

var zipFastest = Benchmark($"System.IO.Compression.ZipArchive Fastest", srcBytes.ToArray(), dstBytes,
(s, d) => CompressZip(s, d, CompressionLevel.Fastest), DecompressZip);
var zipOptimal = Benchmark($"System.IO.Compression.ZipArchive Optimal", srcBytes.ToArray(), dstBytes,
(s, d) => CompressZip(s, d, CompressionLevel.Optimal), DecompressZip);
results.Add(zipFastest);
results.Add(zipOptimal);
// // DotFastLZ fastlz
// var fastlzLv1 = Benchmark($"DotFastLZ.Compression L1", filename, srcBytes.ToArray(), dstBytes, CompressDotFastLZL1, DecompressDotFastLZ);
// var fastlzLv2 = Benchmark($"DotFastLZ.Compression L2", filename, srcBytes.ToArray(), dstBytes, CompressDotFastLZL2, DecompressDotFastLZ);
// results.Add(fastlzLv1);
// results.Add(fastlzLv2);
//
// // K4os LZ4
// var k4osL01 = Benchmark($"K4os.Compression.LZ4 L00", filename,
// srcBytes.ToArray(), dstBytes, (s, d) => CompressK4osLZ4(s, d, LZ4Level.L00_FAST), DecompressK4osLZ4);
// var k4osL12 = Benchmark($"K4os.Compression.LZ4 L12", filename,
// srcBytes.ToArray(), dstBytes, (s, d) => CompressK4osLZ4(s, d, LZ4Level.L12_MAX), DecompressK4osLZ4);
// var k4osL03HC = Benchmark($"K4os.Compression.LZ4 L03_HC", filename,
// srcBytes.ToArray(), dstBytes, (s, d) => CompressK4osLZ4(s, d, LZ4Level.L03_HC), DecompressK4osLZ4);
// var k4osL09HC = Benchmark($"K4os.Compression.LZ4 L09_HC", filename,
// srcBytes.ToArray(), dstBytes, (s, d) => CompressK4osLZ4(s, d, LZ4Level.L09_HC), DecompressK4osLZ4);
// results.Add(k4osL01);
// results.Add(k4osL12);
// results.Add(k4osL03HC);
// results.Add(k4osL09HC);
//
// var zipFastest = Benchmark($"System.IO.Compression.ZipArchive Fastest", filename,
// srcBytes.ToArray(), dstBytes, (s, d) => CompressZip(s, d, CompressionLevel.Fastest), DecompressZip);
// var zipOptimal = Benchmark($"System.IO.Compression.ZipArchive Optimal", filename,
// srcBytes.ToArray(), dstBytes, (s, d) => CompressZip(s, d, CompressionLevel.Optimal), DecompressZip);
// results.Add(zipFastest);
// results.Add(zipOptimal);

return results;
}

private static BenchmarkResult Benchmark(string name, byte[] srcBytes, byte[] dstBytes, Func<byte[], byte[], long> compress, Func<byte[], long, byte[], long> decompress)
{
long compressionSourceByteLength = srcBytes.Length;

var result = new BenchmarkResult();
result.Name = name;
result.Compression.ElapsedWatch = new Stopwatch();
result.Compression.ElapsedWatch.Start();
for (int i = 0; i < 5; ++i)
{
long size = compress.Invoke(srcBytes, dstBytes);
result.Compression.InputBytes += compressionSourceByteLength;
result.Compression.OutputBytes += size;
result.Times += 1;
}

result.Compression.ElapsedWatch.Stop();

var decompInputLength = result.Compression.OutputBytes / result.Times;
//dstBytes.AsSpan(0, (int)(compressedResult.DestBytes / compressedResult.Times)).CopyTo(srcBytes);

result.Decompression.ElapsedWatch = new Stopwatch();
result.Decompression.ElapsedWatch.Start();
for (int i = 0; i < 5; ++i)
{
long size = decompress.Invoke(dstBytes, decompInputLength, srcBytes);
result.Decompression.InputBytes += decompInputLength;
result.Decompression.OutputBytes += size;
result.Times += 1;
}

result.Decompression.ElapsedWatch.Stop();

//Console.WriteLine(result.ToString());
return result;
}


private static long CompressMemcpy(byte[] srcBytes, byte[] dstBytes)
{
srcBytes.CopyTo(new Span<byte>(dstBytes));
return srcBytes.Length;
}

private static long DecompressMemcpy(byte[] srcBytes, long size, byte[] dstBytes)
{
srcBytes.AsSpan(0, (int)size).CopyTo(new Span<byte>(dstBytes));
return size;
}


private static long CompressZip(byte[] srcBytes, byte[] dstBytes, CompressionLevel level)
{
Expand Down Expand Up @@ -195,47 +149,58 @@ private static void Print(string headline, List<BenchmarkResult> results)
for (int i = 0; i < rows.Count; i++)
{
widths[0] = Math.Max(rows[i].Name.Length, widths[0]);
widths[1] = Math.Max(rows[i].Compression.ToSpeedString().Length, widths[1]);
widths[2] = Math.Max(rows[i].Decompression.ToSpeedString().Length, widths[2]);
widths[3] = Math.Max(rows[i].Compression.ToRateString().Length, widths[3]);
widths[1] = Math.Max(rows[i].FileName.Length, widths[1]);
widths[2] = Math.Max(rows[i].ToSourceKbString().Length, widths[2]);
widths[3] = Math.Max(rows[i].Compression.ToSpeedString().Length, widths[3]);
widths[4] = Math.Max(rows[i].Decompression.ToSpeedString().Length, widths[4]);
widths[5] = Math.Max(rows[i].Compression.ToRateString().Length, widths[5]);
}

var headName = "Name";
var headFilename = "Filename";
var headFileSize = "File kB";
var headCompMbs = "Comp. MB/s";
var headDecompMbs = "Decomp. MB/s";
var headRate = "Rate";

widths[0] = Math.Max(widths[0], headName.Length) + 1;
widths[1] = Math.Max(widths[1], headCompMbs.Length) + 1;
widths[2] = Math.Max(widths[2], headDecompMbs.Length) + 1;
widths[3] = Math.Max(widths[3], headRate.Length) + 1;
widths[1] = Math.Max(widths[1], headFilename.Length) + 1;
widths[2] = Math.Max(widths[2], headFileSize.Length) + 1;
widths[3] = Math.Max(widths[3], headCompMbs.Length) + 1;
widths[4] = Math.Max(widths[4], headDecompMbs.Length) + 1;
widths[5] = Math.Max(widths[5], headRate.Length) + 1;

Console.WriteLine();
Console.WriteLine($"### {headline} ###");
Console.WriteLine();



// 표 출력
Console.WriteLine("| " +
headName + new string(' ', widths[0] - headName.Length) + "| " +
headCompMbs + new string(' ', widths[1] - headCompMbs.Length) + "| " +
headDecompMbs + new string(' ', widths[2] - headDecompMbs.Length) + "| " +
headRate + new string(' ', widths[3] - headRate.Length) + "|");
headFilename + new string(' ', widths[1] - headFilename.Length) + "| " +
headFileSize + new string(' ', widths[2] - headFileSize.Length) + "| " +
headCompMbs + new string(' ', widths[3] - headCompMbs.Length) + "| " +
headDecompMbs + new string(' ', widths[4] - headDecompMbs.Length) + "| " +
headRate + new string(' ', widths[5] - headRate.Length) + "|");
Console.WriteLine("|-" +
new string('-', widths[0]) + "|-" +
new string('-', widths[1]) + "|-" +
new string('-', widths[2]) + "|-" +
new string('-', widths[3]) + "|");
new string('-', widths[3]) + "|-" +
new string('-', widths[4]) + "|-" +
new string('-', widths[5]) + "|");

foreach (var row in rows)
{
Console.WriteLine(
"| " +
row.Name.PadRight(widths[0]) + "| " +
row.Compression.ToSpeedString().PadRight(widths[1]) + "| " +
row.Decompression.ToSpeedString().PadRight(widths[2]) + "| " +
row.Compression.ToRateString().PadRight(widths[3]) + "|"
row.FileName.PadRight(widths[1]) + "| " +
row.ToSourceKbString().PadRight(widths[2]) + "| " +
row.Compression.ToSpeedString().PadRight(widths[3]) + "| " +
row.Decompression.ToSpeedString().PadRight(widths[4]) + "| " +
row.Compression.ToRateString().PadRight(widths[5]) + "|"
);
}
}
Expand Down

0 comments on commit eb3cc98

Please sign in to comment.