| OLD | NEW |
| (Empty) |
| 1 // LzmaBench.cs | |
| 2 | |
| 3 using System; | |
| 4 using System.IO; | |
| 5 | |
| 6 namespace SevenZip | |
| 7 { | |
| 8 /// <summary> | |
| 9 /// LZMA Benchmark | |
| 10 /// </summary> | |
| 11 internal abstract class LzmaBench | |
| 12 { | |
| 13 const UInt32 kAdditionalSize = (6 << 20); | |
| 14 const UInt32 kCompressedAdditionalSize = (1 << 10); | |
| 15 const UInt32 kMaxLzmaPropSize = 10; | |
| 16 | |
| 17 class CRandomGenerator | |
| 18 { | |
| 19 UInt32 A1; | |
| 20 UInt32 A2; | |
| 21 public CRandomGenerator() { Init(); } | |
| 22 public void Init() { A1 = 362436069; A2 = 521288629; } | |
| 23 public UInt32 GetRnd() | |
| 24 { | |
| 25 return | |
| 26 ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16
)) << 16) ^ | |
| 27 ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16
))); | |
| 28 } | |
| 29 }; | |
| 30 | |
| 31 class CBitRandomGenerator | |
| 32 { | |
| 33 CRandomGenerator RG = new CRandomGenerator(); | |
| 34 UInt32 Value; | |
| 35 int NumBits; | |
| 36 public void Init() | |
| 37 { | |
| 38 Value = 0; | |
| 39 NumBits = 0; | |
| 40 } | |
| 41 public UInt32 GetRnd(int numBits) | |
| 42 { | |
| 43 UInt32 result; | |
| 44 if (NumBits > numBits) | |
| 45 { | |
| 46 result = Value & (((UInt32)1 << numBits)
- 1); | |
| 47 Value >>= numBits; | |
| 48 NumBits -= numBits; | |
| 49 return result; | |
| 50 } | |
| 51 numBits -= NumBits; | |
| 52 result = (Value << numBits); | |
| 53 Value = RG.GetRnd(); | |
| 54 result |= Value & (((UInt32)1 << numBits) - 1); | |
| 55 Value >>= numBits; | |
| 56 NumBits = 32 - numBits; | |
| 57 return result; | |
| 58 } | |
| 59 }; | |
| 60 | |
| 61 class CBenchRandomGenerator | |
| 62 { | |
| 63 CBitRandomGenerator RG = new CBitRandomGenerator(); | |
| 64 UInt32 Pos; | |
| 65 UInt32 Rep0; | |
| 66 | |
| 67 public UInt32 BufferSize; | |
| 68 public Byte[] Buffer = null; | |
| 69 | |
| 70 public CBenchRandomGenerator() { } | |
| 71 | |
| 72 public void Set(UInt32 bufferSize) | |
| 73 { | |
| 74 Buffer = new Byte[bufferSize]; | |
| 75 Pos = 0; | |
| 76 BufferSize = bufferSize; | |
| 77 } | |
| 78 UInt32 GetRndBit() { return RG.GetRnd(1); } | |
| 79 UInt32 GetLogRandBits(int numBits) | |
| 80 { | |
| 81 UInt32 len = RG.GetRnd(numBits); | |
| 82 return RG.GetRnd((int)len); | |
| 83 } | |
| 84 UInt32 GetOffset() | |
| 85 { | |
| 86 if (GetRndBit() == 0) | |
| 87 return GetLogRandBits(4); | |
| 88 return (GetLogRandBits(4) << 10) | RG.GetRnd(10)
; | |
| 89 } | |
| 90 UInt32 GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2
)); } | |
| 91 UInt32 GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2
)); } | |
| 92 public void Generate() | |
| 93 { | |
| 94 RG.Init(); | |
| 95 Rep0 = 1; | |
| 96 while (Pos < BufferSize) | |
| 97 { | |
| 98 if (GetRndBit() == 0 || Pos < 1) | |
| 99 Buffer[Pos++] = (Byte)RG.GetRnd(
8); | |
| 100 else | |
| 101 { | |
| 102 UInt32 len; | |
| 103 if (RG.GetRnd(3) == 0) | |
| 104 len = 1 + GetLen1(); | |
| 105 else | |
| 106 { | |
| 107 do | |
| 108 Rep0 = GetOffset
(); | |
| 109 while (Rep0 >= Pos); | |
| 110 Rep0++; | |
| 111 len = 2 + GetLen2(); | |
| 112 } | |
| 113 for (UInt32 i = 0; i < len && Po
s < BufferSize; i++, Pos++) | |
| 114 Buffer[Pos] = Buffer[Pos
- Rep0]; | |
| 115 } | |
| 116 } | |
| 117 } | |
| 118 }; | |
| 119 | |
| 120 class CrcOutStream : System.IO.Stream | |
| 121 { | |
| 122 public CRC CRC = new CRC(); | |
| 123 public void Init() { CRC.Init(); } | |
| 124 public UInt32 GetDigest() { return CRC.GetDigest(); } | |
| 125 | |
| 126 public override bool CanRead { get { return false; } } | |
| 127 public override bool CanSeek { get { return false; } } | |
| 128 public override bool CanWrite { get { return true; } } | |
| 129 public override Int64 Length { get { return 0; } } | |
| 130 public override Int64 Position { get { return 0; } set {
} } | |
| 131 public override void Flush() { } | |
| 132 public override long Seek(long offset, SeekOrigin origin
) { return 0; } | |
| 133 public override void SetLength(long value) { } | |
| 134 public override int Read(byte[] buffer, int offset, int
count) { return 0; } | |
| 135 | |
| 136 public override void WriteByte(byte b) | |
| 137 { | |
| 138 CRC.UpdateByte(b); | |
| 139 } | |
| 140 public override void Write(byte[] buffer, int offset, in
t count) | |
| 141 { | |
| 142 CRC.Update(buffer, (uint)offset, (uint)count); | |
| 143 } | |
| 144 }; | |
| 145 | |
| 146 class CProgressInfo : ICodeProgress | |
| 147 { | |
| 148 public Int64 ApprovedStart; | |
| 149 public Int64 InSize; | |
| 150 public System.DateTime Time; | |
| 151 public void Init() { InSize = 0; } | |
| 152 public void SetProgress(Int64 inSize, Int64 outSize) | |
| 153 { | |
| 154 if (inSize >= ApprovedStart && InSize == 0) | |
| 155 { | |
| 156 Time = DateTime.UtcNow; | |
| 157 InSize = inSize; | |
| 158 } | |
| 159 } | |
| 160 } | |
| 161 const int kSubBits = 8; | |
| 162 | |
| 163 static UInt32 GetLogSize(UInt32 size) | |
| 164 { | |
| 165 for (int i = kSubBits; i < 32; i++) | |
| 166 for (UInt32 j = 0; j < (1 << kSubBits); j++) | |
| 167 if (size <= (((UInt32)1) << i) + (j << (
i - kSubBits))) | |
| 168 return (UInt32)(i << kSubBits) +
j; | |
| 169 return (32 << kSubBits); | |
| 170 } | |
| 171 | |
| 172 static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime) | |
| 173 { | |
| 174 UInt64 freq = TimeSpan.TicksPerSecond; | |
| 175 UInt64 elTime = elapsedTime; | |
| 176 while (freq > 1000000) | |
| 177 { | |
| 178 freq >>= 1; | |
| 179 elTime >>= 1; | |
| 180 } | |
| 181 if (elTime == 0) | |
| 182 elTime = 1; | |
| 183 return value * freq / elTime; | |
| 184 } | |
| 185 | |
| 186 static UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 el
apsedTime, UInt64 size) | |
| 187 { | |
| 188 UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits)
; | |
| 189 UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 *
kSubBits)); | |
| 190 UInt64 numCommands = (UInt64)(size) * numCommandsForOne; | |
| 191 return MyMultDiv64(numCommands, elapsedTime); | |
| 192 } | |
| 193 | |
| 194 static UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 out
Size, UInt64 inSize) | |
| 195 { | |
| 196 UInt64 numCommands = inSize * 220 + outSize * 20; | |
| 197 return MyMultDiv64(numCommands, elapsedTime); | |
| 198 } | |
| 199 | |
| 200 static UInt64 GetTotalRating( | |
| 201 UInt32 dictionarySize, | |
| 202 UInt64 elapsedTimeEn, UInt64 sizeEn, | |
| 203 UInt64 elapsedTimeDe, | |
| 204 UInt64 inSizeDe, UInt64 outSizeDe) | |
| 205 { | |
| 206 return (GetCompressRating(dictionarySize, elapsedTimeEn,
sizeEn) + | |
| 207 GetDecompressRating(elapsedTimeDe, inSizeDe, out
SizeDe)) / 2; | |
| 208 } | |
| 209 | |
| 210 static void PrintValue(UInt64 v) | |
| 211 { | |
| 212 string s = v.ToString(); | |
| 213 for (int i = 0; i + s.Length < 6; i++) | |
| 214 System.Console.Write(" "); | |
| 215 System.Console.Write(s); | |
| 216 } | |
| 217 | |
| 218 static void PrintRating(UInt64 rating) | |
| 219 { | |
| 220 PrintValue(rating / 1000000); | |
| 221 System.Console.Write(" MIPS"); | |
| 222 } | |
| 223 | |
| 224 static void PrintResults( | |
| 225 UInt32 dictionarySize, | |
| 226 UInt64 elapsedTime, | |
| 227 UInt64 size, | |
| 228 bool decompressMode, UInt64 secondSize) | |
| 229 { | |
| 230 UInt64 speed = MyMultDiv64(size, elapsedTime); | |
| 231 PrintValue(speed / 1024); | |
| 232 System.Console.Write(" KB/s "); | |
| 233 UInt64 rating; | |
| 234 if (decompressMode) | |
| 235 rating = GetDecompressRating(elapsedTime, size,
secondSize); | |
| 236 else | |
| 237 rating = GetCompressRating(dictionarySize, elaps
edTime, size); | |
| 238 PrintRating(rating); | |
| 239 } | |
| 240 | |
| 241 static public int LzmaBenchmark(Int32 numIterations, UInt32 dict
ionarySize) | |
| 242 { | |
| 243 if (numIterations <= 0) | |
| 244 return 0; | |
| 245 if (dictionarySize < (1 << 18)) | |
| 246 { | |
| 247 System.Console.WriteLine("\nError: dictionary si
ze for benchmark must be >= 19 (512 KB)"); | |
| 248 return 1; | |
| 249 } | |
| 250 System.Console.Write("\n Compressing
Decompressing\n\n"); | |
| 251 | |
| 252 Compression.LZMA.Encoder encoder = new Compression.LZMA.
Encoder(); | |
| 253 Compression.LZMA.Decoder decoder = new Compression.LZMA.
Decoder(); | |
| 254 | |
| 255 | |
| 256 CoderPropID[] propIDs = | |
| 257 { | |
| 258 CoderPropID.DictionarySize, | |
| 259 }; | |
| 260 object[] properties = | |
| 261 { | |
| 262 (Int32)(dictionarySize), | |
| 263 }; | |
| 264 | |
| 265 UInt32 kBufferSize = dictionarySize + kAdditionalSize; | |
| 266 UInt32 kCompressedBufferSize = (kBufferSize / 2) + kComp
ressedAdditionalSize; | |
| 267 | |
| 268 encoder.SetCoderProperties(propIDs, properties); | |
| 269 System.IO.MemoryStream propStream = new System.IO.Memory
Stream(); | |
| 270 encoder.WriteCoderProperties(propStream); | |
| 271 byte[] propArray = propStream.ToArray(); | |
| 272 | |
| 273 CBenchRandomGenerator rg = new CBenchRandomGenerator(); | |
| 274 | |
| 275 rg.Set(kBufferSize); | |
| 276 rg.Generate(); | |
| 277 CRC crc = new CRC(); | |
| 278 crc.Init(); | |
| 279 crc.Update(rg.Buffer, 0, rg.BufferSize); | |
| 280 | |
| 281 CProgressInfo progressInfo = new CProgressInfo(); | |
| 282 progressInfo.ApprovedStart = dictionarySize; | |
| 283 | |
| 284 UInt64 totalBenchSize = 0; | |
| 285 UInt64 totalEncodeTime = 0; | |
| 286 UInt64 totalDecodeTime = 0; | |
| 287 UInt64 totalCompressedSize = 0; | |
| 288 | |
| 289 MemoryStream inStream = new MemoryStream(rg.Buffer, 0, (
int)rg.BufferSize); | |
| 290 MemoryStream compressedStream = new MemoryStream((int)kC
ompressedBufferSize); | |
| 291 CrcOutStream crcOutStream = new CrcOutStream(); | |
| 292 for (Int32 i = 0; i < numIterations; i++) | |
| 293 { | |
| 294 progressInfo.Init(); | |
| 295 inStream.Seek(0, SeekOrigin.Begin); | |
| 296 compressedStream.Seek(0, SeekOrigin.Begin); | |
| 297 encoder.Code(inStream, compressedStream, -1, -1,
progressInfo); | |
| 298 TimeSpan sp2 = DateTime.UtcNow - progressInfo.Ti
me; | |
| 299 UInt64 encodeTime = (UInt64)sp2.Ticks; | |
| 300 | |
| 301 long compressedSize = compressedStream.Position; | |
| 302 if (progressInfo.InSize == 0) | |
| 303 throw (new Exception("Internal ERROR 128
2")); | |
| 304 | |
| 305 UInt64 decodeTime = 0; | |
| 306 for (int j = 0; j < 2; j++) | |
| 307 { | |
| 308 compressedStream.Seek(0, SeekOrigin.Begi
n); | |
| 309 crcOutStream.Init(); | |
| 310 | |
| 311 decoder.SetDecoderProperties(propArray); | |
| 312 UInt64 outSize = kBufferSize; | |
| 313 System.DateTime startTime = DateTime.Utc
Now; | |
| 314 decoder.Code(compressedStream, crcOutStr
eam, 0, (Int64)outSize, null); | |
| 315 TimeSpan sp = (DateTime.UtcNow - startTi
me); | |
| 316 decodeTime = (ulong)sp.Ticks; | |
| 317 if (crcOutStream.GetDigest() != crc.GetD
igest()) | |
| 318 throw (new Exception("CRC Error"
)); | |
| 319 } | |
| 320 UInt64 benchSize = kBufferSize - (UInt64)progres
sInfo.InSize; | |
| 321 PrintResults(dictionarySize, encodeTime, benchSi
ze, false, 0); | |
| 322 System.Console.Write(" "); | |
| 323 PrintResults(dictionarySize, decodeTime, kBuffer
Size, true, (ulong)compressedSize); | |
| 324 System.Console.WriteLine(); | |
| 325 | |
| 326 totalBenchSize += benchSize; | |
| 327 totalEncodeTime += encodeTime; | |
| 328 totalDecodeTime += decodeTime; | |
| 329 totalCompressedSize += (ulong)compressedSize; | |
| 330 } | |
| 331 System.Console.WriteLine("------------------------------
---------------------"); | |
| 332 PrintResults(dictionarySize, totalEncodeTime, totalBench
Size, false, 0); | |
| 333 System.Console.Write(" "); | |
| 334 PrintResults(dictionarySize, totalDecodeTime, | |
| 335 kBufferSize * (UInt64)numIterations, tru
e, totalCompressedSize); | |
| 336 System.Console.WriteLine(" Average"); | |
| 337 return 0; | |
| 338 } | |
| 339 } | |
| 340 } | |
| OLD | NEW |