123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- // 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;
- }
- }
- }
|