Source code

Revision control

Copy as Markdown

Other Tools

// LzmaBench.cs↩
using System;↩
using System.IO;↩
namespace SevenZip↩
{↩
/// <summary>↩
/// LZMA Benchmark↩
/// </summary>↩
internal abstract class LzmaBench↩
{↩
const UInt32 kAdditionalSize = (6 << 20);↩
const UInt32 kCompressedAdditionalSize = (1 << 10);↩
const UInt32 kMaxLzmaPropSize = 10;↩
class CRandomGenerator↩
{↩
UInt32 A1;↩
UInt32 A2;↩
public CRandomGenerator() { Init(); }↩
public void Init() { A1 = 362436069; A2 = 521288629; }↩
public UInt32 GetRnd()↩
{↩
return↩
((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^↩
((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)));↩
}↩
};↩
class CBitRandomGenerator↩
{↩
CRandomGenerator RG = new CRandomGenerator();↩
UInt32 Value;↩
int NumBits;↩
public void Init()↩
{↩
Value = 0;↩
NumBits = 0;↩
}↩
public UInt32 GetRnd(int numBits)↩
{↩
UInt32 result;↩
if (NumBits > numBits)↩
{↩
result = Value & (((UInt32)1 << numBits) - 1);↩
Value >>= numBits;↩
NumBits -= numBits;↩
return result;↩
}↩
numBits -= NumBits;↩
result = (Value << numBits);↩
Value = RG.GetRnd();↩
result |= Value & (((UInt32)1 << numBits) - 1);↩
Value >>= numBits;↩
NumBits = 32 - numBits;↩
return result;↩
}↩
};↩
class CBenchRandomGenerator↩
{↩
CBitRandomGenerator RG = new CBitRandomGenerator();↩
UInt32 Pos;↩
UInt32 Rep0;↩
public UInt32 BufferSize;↩
public Byte[] Buffer = null;↩
public CBenchRandomGenerator() { }↩
public void Set(UInt32 bufferSize)↩
{↩
Buffer = new Byte[bufferSize];↩
Pos = 0;↩
BufferSize = bufferSize;↩
}↩
UInt32 GetRndBit() { return RG.GetRnd(1); }↩
UInt32 GetLogRandBits(int numBits)↩
{↩
UInt32 len = RG.GetRnd(numBits);↩
return RG.GetRnd((int)len);↩
}↩
UInt32 GetOffset()↩
{↩
if (GetRndBit() == 0)↩
return GetLogRandBits(4);↩
return (GetLogRandBits(4) << 10) | RG.GetRnd(10);↩
}↩
UInt32 GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }↩
UInt32 GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }↩
public void Generate()↩
{↩
RG.Init();↩
Rep0 = 1;↩
while (Pos < BufferSize)↩
{↩
if (GetRndBit() == 0 || Pos < 1)↩
Buffer[Pos++] = (Byte)RG.GetRnd(8);↩
else↩
{↩
UInt32 len;↩
if (RG.GetRnd(3) == 0)↩
len = 1 + GetLen1();↩
else↩
{↩
do↩
Rep0 = GetOffset();↩
while (Rep0 >= Pos);↩
Rep0++;↩
len = 2 + GetLen2();↩
}↩
for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++)↩
Buffer[Pos] = Buffer[Pos - Rep0];↩
}↩
}↩
}↩
};↩
class CrcOutStream : System.IO.Stream↩
{↩
public CRC CRC = new CRC();↩
public void Init() { CRC.Init(); }↩
public UInt32 GetDigest() { return CRC.GetDigest(); }↩
public override bool CanRead { get { return false; } }↩
public override bool CanSeek { get { return false; } }↩
public override bool CanWrite { get { return true; } }↩
public override Int64 Length { get { return 0; } }↩
public override Int64 Position { get { return 0; } set { } }↩
public override void Flush() { }↩
public override long Seek(long offset, SeekOrigin origin) { return 0; }↩
public override void SetLength(long value) { }↩
public override int Read(byte[] buffer, int offset, int count) { return 0; }↩
public override void WriteByte(byte b)↩
{↩
CRC.UpdateByte(b);↩
}↩
public override void Write(byte[] buffer, int offset, int count)↩
{↩
CRC.Update(buffer, (uint)offset, (uint)count);↩
}↩
};↩
class CProgressInfo : ICodeProgress↩
{↩
public Int64 ApprovedStart;↩
public Int64 InSize;↩
public System.DateTime Time;↩
public void Init() { InSize = 0; }↩
public void SetProgress(Int64 inSize, Int64 outSize)↩
{↩
if (inSize >= ApprovedStart && InSize == 0)↩
{↩
Time = DateTime.UtcNow;↩
InSize = inSize;↩
}↩
}↩
}↩
const int kSubBits = 8;↩
static UInt32 GetLogSize(UInt32 size)↩
{↩
for (int i = kSubBits; i < 32; i++)↩
for (UInt32 j = 0; j < (1 << kSubBits); j++)↩
if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))↩
return (UInt32)(i << kSubBits) + j;↩
return (32 << kSubBits);↩
}↩
static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime)↩
{↩
UInt64 freq = TimeSpan.TicksPerSecond;↩
UInt64 elTime = elapsedTime;↩
while (freq > 1000000)↩
{↩
freq >>= 1;↩
elTime >>= 1;↩
}↩
if (elTime == 0)↩
elTime = 1;↩
return value * freq / elTime;↩
}↩
static UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 size)↩
{↩
UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits);↩
UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));↩
UInt64 numCommands = (UInt64)(size) * numCommandsForOne;↩
return MyMultDiv64(numCommands, elapsedTime);↩
}↩
static UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 outSize, UInt64 inSize)↩
{↩
UInt64 numCommands = inSize * 220 + outSize * 20;↩
return MyMultDiv64(numCommands, elapsedTime);↩
}↩
static UInt64 GetTotalRating(↩
UInt32 dictionarySize,↩
UInt64 elapsedTimeEn, UInt64 sizeEn,↩
UInt64 elapsedTimeDe,↩
UInt64 inSizeDe, UInt64 outSizeDe)↩
{↩
return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +↩
GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;↩
}↩
static void PrintValue(UInt64 v)↩
{↩
string s = v.ToString();↩
for (int i = 0; i + s.Length < 6; i++)↩
System.Console.Write(" ");↩
System.Console.Write(s);↩
}↩
static void PrintRating(UInt64 rating)↩
{↩
PrintValue(rating / 1000000);↩
System.Console.Write(" MIPS");↩
}↩
static void PrintResults(↩
UInt32 dictionarySize,↩
UInt64 elapsedTime,↩
UInt64 size,↩
bool decompressMode, UInt64 secondSize)↩
{↩
UInt64 speed = MyMultDiv64(size, elapsedTime);↩
PrintValue(speed / 1024);↩
System.Console.Write(" KB/s ");↩
UInt64 rating;↩
if (decompressMode)↩
rating = GetDecompressRating(elapsedTime, size, secondSize);↩
else↩
rating = GetCompressRating(dictionarySize, elapsedTime, size);↩
PrintRating(rating);↩
}↩
static public int LzmaBenchmark(Int32 numIterations, UInt32 dictionarySize)↩
{↩
if (numIterations <= 0)↩
return 0;↩
if (dictionarySize < (1 << 18))↩
{↩
System.Console.WriteLine("\nError: dictionary size for benchmark must be >= 19 (512 KB)");↩
return 1;↩
}↩
System.Console.Write("\n Compressing Decompressing\n\n");↩
Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder();↩
Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();↩
CoderPropID[] propIDs = ↩
{ ↩
CoderPropID.DictionarySize,↩
};↩
object[] properties = ↩
{↩
(Int32)(dictionarySize),↩
};↩
UInt32 kBufferSize = dictionarySize + kAdditionalSize;↩
UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;↩
encoder.SetCoderProperties(propIDs, properties);↩
System.IO.MemoryStream propStream = new System.IO.MemoryStream();↩
encoder.WriteCoderProperties(propStream);↩
byte[] propArray = propStream.ToArray();↩
CBenchRandomGenerator rg = new CBenchRandomGenerator();↩
rg.Set(kBufferSize);↩
rg.Generate();↩
CRC crc = new CRC();↩
crc.Init();↩
crc.Update(rg.Buffer, 0, rg.BufferSize);↩
CProgressInfo progressInfo = new CProgressInfo();↩
progressInfo.ApprovedStart = dictionarySize;↩
UInt64 totalBenchSize = 0;↩
UInt64 totalEncodeTime = 0;↩
UInt64 totalDecodeTime = 0;↩
UInt64 totalCompressedSize = 0;↩
MemoryStream inStream = new MemoryStream(rg.Buffer, 0, (int)rg.BufferSize);↩
MemoryStream compressedStream = new MemoryStream((int)kCompressedBufferSize);↩
CrcOutStream crcOutStream = new CrcOutStream();↩
for (Int32 i = 0; i < numIterations; i++)↩
{↩
progressInfo.Init();↩
inStream.Seek(0, SeekOrigin.Begin);↩
compressedStream.Seek(0, SeekOrigin.Begin);↩
encoder.Code(inStream, compressedStream, -1, -1, progressInfo);↩
TimeSpan sp2 = DateTime.UtcNow - progressInfo.Time;↩
UInt64 encodeTime = (UInt64)sp2.Ticks;↩
long compressedSize = compressedStream.Position;↩
if (progressInfo.InSize == 0)↩
throw (new Exception("Internal ERROR 1282"));↩
UInt64 decodeTime = 0;↩
for (int j = 0; j < 2; j++)↩
{↩
compressedStream.Seek(0, SeekOrigin.Begin);↩
crcOutStream.Init();↩
decoder.SetDecoderProperties(propArray);↩
UInt64 outSize = kBufferSize;↩
System.DateTime startTime = DateTime.UtcNow;↩
decoder.Code(compressedStream, crcOutStream, 0, (Int64)outSize, null);↩
TimeSpan sp = (DateTime.UtcNow - startTime);↩
decodeTime = (ulong)sp.Ticks;↩
if (crcOutStream.GetDigest() != crc.GetDigest())↩
throw (new Exception("CRC Error"));↩
}↩
UInt64 benchSize = kBufferSize - (UInt64)progressInfo.InSize;↩
PrintResults(dictionarySize, encodeTime, benchSize, false, 0);↩
System.Console.Write(" ");↩
PrintResults(dictionarySize, decodeTime, kBufferSize, true, (ulong)compressedSize);↩
System.Console.WriteLine();↩
totalBenchSize += benchSize;↩
totalEncodeTime += encodeTime;↩
totalDecodeTime += decodeTime;↩
totalCompressedSize += (ulong)compressedSize;↩
}↩
System.Console.WriteLine("---------------------------------------------------");↩
PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);↩
System.Console.Write(" ");↩
PrintResults(dictionarySize, totalDecodeTime,↩
kBufferSize * (UInt64)numIterations, true, totalCompressedSize);↩
System.Console.WriteLine(" Average");↩
return 0;↩
}↩
}↩
}↩