| OLD | NEW |
| (Empty) |
| 1 package SevenZip; | |
| 2 | |
| 3 import java.io.ByteArrayOutputStream; | |
| 4 import java.io.ByteArrayInputStream; | |
| 5 import java.io.IOException; | |
| 6 | |
| 7 public class LzmaBench | |
| 8 { | |
| 9 static final int kAdditionalSize = (1 << 21); | |
| 10 static final int kCompressedAdditionalSize = (1 << 10); | |
| 11 | |
| 12 static class CRandomGenerator | |
| 13 { | |
| 14 int A1; | |
| 15 int A2; | |
| 16 public CRandomGenerator() { Init(); } | |
| 17 public void Init() { A1 = 362436069; A2 = 521288629; } | |
| 18 public int GetRnd() | |
| 19 { | |
| 20 return | |
| 21 ((A1 = 36969 * (A1 & 0xffff) + (A1 >>> 16)) << 1
6) ^ | |
| 22 ((A2 = 18000 * (A2 & 0xffff) + (A2 >>> 16))); | |
| 23 } | |
| 24 }; | |
| 25 | |
| 26 static class CBitRandomGenerator | |
| 27 { | |
| 28 CRandomGenerator RG = new CRandomGenerator(); | |
| 29 int Value; | |
| 30 int NumBits; | |
| 31 public void Init() | |
| 32 { | |
| 33 Value = 0; | |
| 34 NumBits = 0; | |
| 35 } | |
| 36 public int GetRnd(int numBits) | |
| 37 { | |
| 38 int result; | |
| 39 if (NumBits > numBits) | |
| 40 { | |
| 41 result = Value & ((1 << numBits) - 1); | |
| 42 Value >>>= numBits; | |
| 43 NumBits -= numBits; | |
| 44 return result; | |
| 45 } | |
| 46 numBits -= NumBits; | |
| 47 result = (Value << numBits); | |
| 48 Value = RG.GetRnd(); | |
| 49 result |= Value & (((int)1 << numBits) - 1); | |
| 50 Value >>>= numBits; | |
| 51 NumBits = 32 - numBits; | |
| 52 return result; | |
| 53 } | |
| 54 }; | |
| 55 | |
| 56 static class CBenchRandomGenerator | |
| 57 { | |
| 58 CBitRandomGenerator RG = new CBitRandomGenerator(); | |
| 59 int Pos; | |
| 60 int Rep0; | |
| 61 | |
| 62 public int BufferSize; | |
| 63 public byte[] Buffer = null; | |
| 64 | |
| 65 public CBenchRandomGenerator() { } | |
| 66 public void Set(int bufferSize) | |
| 67 { | |
| 68 Buffer = new byte[bufferSize]; | |
| 69 Pos = 0; | |
| 70 BufferSize = bufferSize; | |
| 71 } | |
| 72 int GetRndBit() { return RG.GetRnd(1); } | |
| 73 int GetLogRandBits(int numBits) | |
| 74 { | |
| 75 int len = RG.GetRnd(numBits); | |
| 76 return RG.GetRnd((int)len); | |
| 77 } | |
| 78 int GetOffset() | |
| 79 { | |
| 80 if (GetRndBit() == 0) | |
| 81 return GetLogRandBits(4); | |
| 82 return (GetLogRandBits(4) << 10) | RG.GetRnd(10); | |
| 83 } | |
| 84 int GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); } | |
| 85 int GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); } | |
| 86 public void Generate() | |
| 87 { | |
| 88 RG.Init(); | |
| 89 Rep0 = 1; | |
| 90 while (Pos < BufferSize) | |
| 91 { | |
| 92 if (GetRndBit() == 0 || Pos < 1) | |
| 93 Buffer[Pos++] = (byte)(RG.GetRnd(8)); | |
| 94 else | |
| 95 { | |
| 96 int len; | |
| 97 if (RG.GetRnd(3) == 0) | |
| 98 len = 1 + GetLen1(); | |
| 99 else | |
| 100 { | |
| 101 do | |
| 102 Rep0 = GetOffset(); | |
| 103 while (Rep0 >= Pos); | |
| 104 Rep0++; | |
| 105 len = 2 + GetLen2(); | |
| 106 } | |
| 107 for (int i = 0; i < len && Pos < BufferS
ize; i++, Pos++) | |
| 108 Buffer[Pos] = Buffer[Pos - Rep0]
; | |
| 109 } | |
| 110 } | |
| 111 } | |
| 112 }; | |
| 113 | |
| 114 static class CrcOutStream extends java.io.OutputStream | |
| 115 { | |
| 116 public CRC CRC = new CRC(); | |
| 117 | |
| 118 public void Init() | |
| 119 { | |
| 120 CRC.Init(); | |
| 121 } | |
| 122 public int GetDigest() | |
| 123 { | |
| 124 return CRC.GetDigest(); | |
| 125 } | |
| 126 public void write(byte[] b) | |
| 127 { | |
| 128 CRC.Update(b); | |
| 129 } | |
| 130 public void write(byte[] b, int off, int len) | |
| 131 { | |
| 132 CRC.Update(b, off, len); | |
| 133 } | |
| 134 public void write(int b) | |
| 135 { | |
| 136 CRC.UpdateByte(b); | |
| 137 } | |
| 138 }; | |
| 139 | |
| 140 static class MyOutputStream extends java.io.OutputStream | |
| 141 { | |
| 142 byte[] _buffer; | |
| 143 int _size; | |
| 144 int _pos; | |
| 145 | |
| 146 public MyOutputStream(byte[] buffer) | |
| 147 { | |
| 148 _buffer = buffer; | |
| 149 _size = _buffer.length; | |
| 150 } | |
| 151 | |
| 152 public void reset() | |
| 153 { | |
| 154 _pos = 0; | |
| 155 } | |
| 156 | |
| 157 public void write(int b) throws IOException | |
| 158 { | |
| 159 if (_pos >= _size) | |
| 160 throw new IOException("Error"); | |
| 161 _buffer[_pos++] = (byte)b; | |
| 162 } | |
| 163 | |
| 164 public int size() | |
| 165 { | |
| 166 return _pos; | |
| 167 } | |
| 168 }; | |
| 169 | |
| 170 static class MyInputStream extends java.io.InputStream | |
| 171 { | |
| 172 byte[] _buffer; | |
| 173 int _size; | |
| 174 int _pos; | |
| 175 | |
| 176 public MyInputStream(byte[] buffer, int size) | |
| 177 { | |
| 178 _buffer = buffer; | |
| 179 _size = size; | |
| 180 } | |
| 181 | |
| 182 public void reset() | |
| 183 { | |
| 184 _pos = 0; | |
| 185 } | |
| 186 | |
| 187 public int read() | |
| 188 { | |
| 189 if (_pos >= _size) | |
| 190 return -1; | |
| 191 return _buffer[_pos++] & 0xFF; | |
| 192 } | |
| 193 }; | |
| 194 | |
| 195 static class CProgressInfo implements ICodeProgress | |
| 196 { | |
| 197 public long ApprovedStart; | |
| 198 public long InSize; | |
| 199 public long Time; | |
| 200 public void Init() | |
| 201 { InSize = 0; } | |
| 202 public void SetProgress(long inSize, long outSize) | |
| 203 { | |
| 204 if (inSize >= ApprovedStart && InSize == 0) | |
| 205 { | |
| 206 Time = System.currentTimeMillis(); | |
| 207 InSize = inSize; | |
| 208 } | |
| 209 } | |
| 210 } | |
| 211 static final int kSubBits = 8; | |
| 212 | |
| 213 static int GetLogSize(int size) | |
| 214 { | |
| 215 for (int i = kSubBits; i < 32; i++) | |
| 216 for (int j = 0; j < (1 << kSubBits); j++) | |
| 217 if (size <= ((1) << i) + (j << (i - kSubBits))) | |
| 218 return (i << kSubBits) + j; | |
| 219 return (32 << kSubBits); | |
| 220 } | |
| 221 | |
| 222 static long MyMultDiv64(long value, long elapsedTime) | |
| 223 { | |
| 224 long freq = 1000; // ms | |
| 225 long elTime = elapsedTime; | |
| 226 while (freq > 1000000) | |
| 227 { | |
| 228 freq >>>= 1; | |
| 229 elTime >>>= 1; | |
| 230 } | |
| 231 if (elTime == 0) | |
| 232 elTime = 1; | |
| 233 return value * freq / elTime; | |
| 234 } | |
| 235 | |
| 236 static long GetCompressRating(int dictionarySize, long elapsedTime, long
size) | |
| 237 { | |
| 238 long t = GetLogSize(dictionarySize) - (18 << kSubBits); | |
| 239 long numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits))
; | |
| 240 long numCommands = (long)(size) * numCommandsForOne; | |
| 241 return MyMultDiv64(numCommands, elapsedTime); | |
| 242 } | |
| 243 | |
| 244 static long GetDecompressRating(long elapsedTime, long outSize, long inS
ize) | |
| 245 { | |
| 246 long numCommands = inSize * 220 + outSize * 20; | |
| 247 return MyMultDiv64(numCommands, elapsedTime); | |
| 248 } | |
| 249 | |
| 250 static long GetTotalRating( | |
| 251 int dictionarySize, | |
| 252 long elapsedTimeEn, long sizeEn, | |
| 253 long elapsedTimeDe, | |
| 254 long inSizeDe, long outSizeDe) | |
| 255 { | |
| 256 return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn)
+ | |
| 257 GetDecompressRating(elapsedTimeDe, inSizeDe, out
SizeDe)) / 2; | |
| 258 } | |
| 259 | |
| 260 static void PrintValue(long v) | |
| 261 { | |
| 262 String s = ""; | |
| 263 s += v; | |
| 264 for (int i = 0; i + s.length() < 6; i++) | |
| 265 System.out.print(" "); | |
| 266 System.out.print(s); | |
| 267 } | |
| 268 | |
| 269 static void PrintRating(long rating) | |
| 270 { | |
| 271 PrintValue(rating / 1000000); | |
| 272 System.out.print(" MIPS"); | |
| 273 } | |
| 274 | |
| 275 static void PrintResults( | |
| 276 int dictionarySize, | |
| 277 long elapsedTime, | |
| 278 long size, | |
| 279 boolean decompressMode, long secondSize) | |
| 280 { | |
| 281 long speed = MyMultDiv64(size, elapsedTime); | |
| 282 PrintValue(speed / 1024); | |
| 283 System.out.print(" KB/s "); | |
| 284 long rating; | |
| 285 if (decompressMode) | |
| 286 rating = GetDecompressRating(elapsedTime, size, secondSi
ze); | |
| 287 else | |
| 288 rating = GetCompressRating(dictionarySize, elapsedTime,
size); | |
| 289 PrintRating(rating); | |
| 290 } | |
| 291 | |
| 292 static public int LzmaBenchmark(int numIterations, int dictionarySize) t
hrows Exception | |
| 293 { | |
| 294 if (numIterations <= 0) | |
| 295 return 0; | |
| 296 if (dictionarySize < (1 << 18)) | |
| 297 { | |
| 298 System.out.println("\nError: dictionary size for benchma
rk must be >= 18 (256 KB)"); | |
| 299 return 1; | |
| 300 } | |
| 301 System.out.print("\n Compressing Decompress
ing\n\n"); | |
| 302 | |
| 303 SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compres
sion.LZMA.Encoder(); | |
| 304 SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compres
sion.LZMA.Decoder(); | |
| 305 | |
| 306 if (!encoder.SetDictionarySize(dictionarySize)) | |
| 307 throw new Exception("Incorrect dictionary size"); | |
| 308 | |
| 309 int kBufferSize = dictionarySize + kAdditionalSize; | |
| 310 int kCompressedBufferSize = (kBufferSize / 2) + kCompressedAddit
ionalSize; | |
| 311 | |
| 312 ByteArrayOutputStream propStream = new ByteArrayOutputStream(); | |
| 313 encoder.WriteCoderProperties(propStream); | |
| 314 byte[] propArray = propStream.toByteArray(); | |
| 315 decoder.SetDecoderProperties(propArray); | |
| 316 | |
| 317 CBenchRandomGenerator rg = new CBenchRandomGenerator(); | |
| 318 | |
| 319 rg.Set(kBufferSize); | |
| 320 rg.Generate(); | |
| 321 CRC crc = new CRC(); | |
| 322 crc.Init(); | |
| 323 crc.Update(rg.Buffer, 0, rg.BufferSize); | |
| 324 | |
| 325 CProgressInfo progressInfo = new CProgressInfo(); | |
| 326 progressInfo.ApprovedStart = dictionarySize; | |
| 327 | |
| 328 long totalBenchSize = 0; | |
| 329 long totalEncodeTime = 0; | |
| 330 long totalDecodeTime = 0; | |
| 331 long totalCompressedSize = 0; | |
| 332 | |
| 333 MyInputStream inStream = new MyInputStream(rg.Buffer, rg.BufferS
ize); | |
| 334 | |
| 335 byte[] compressedBuffer = new byte[kCompressedBufferSize]; | |
| 336 MyOutputStream compressedStream = new MyOutputStream(compressedB
uffer); | |
| 337 CrcOutStream crcOutStream = new CrcOutStream(); | |
| 338 MyInputStream inputCompressedStream = null; | |
| 339 int compressedSize = 0; | |
| 340 for (int i = 0; i < numIterations; i++) | |
| 341 { | |
| 342 progressInfo.Init(); | |
| 343 inStream.reset(); | |
| 344 compressedStream.reset(); | |
| 345 encoder.Code(inStream, compressedStream, -1, -1, progres
sInfo); | |
| 346 long encodeTime = System.currentTimeMillis() - progressI
nfo.Time; | |
| 347 | |
| 348 if (i == 0) | |
| 349 { | |
| 350 compressedSize = compressedStream.size(); | |
| 351 inputCompressedStream = new MyInputStream(compre
ssedBuffer, compressedSize); | |
| 352 } | |
| 353 else if (compressedSize != compressedStream.size()) | |
| 354 throw (new Exception("Encoding error")); | |
| 355 | |
| 356 if (progressInfo.InSize == 0) | |
| 357 throw (new Exception("Internal ERROR 1282")); | |
| 358 | |
| 359 long decodeTime = 0; | |
| 360 for (int j = 0; j < 2; j++) | |
| 361 { | |
| 362 inputCompressedStream.reset(); | |
| 363 crcOutStream.Init(); | |
| 364 | |
| 365 long outSize = kBufferSize; | |
| 366 long startTime = System.currentTimeMillis(); | |
| 367 if (!decoder.Code(inputCompressedStream, crcOutS
tream, outSize)) | |
| 368 throw (new Exception("Decoding Error"));
; | |
| 369 decodeTime = System.currentTimeMillis() - startT
ime; | |
| 370 if (crcOutStream.GetDigest() != crc.GetDigest()) | |
| 371 throw (new Exception("CRC Error")); | |
| 372 } | |
| 373 long benchSize = kBufferSize - (long)progressInfo.InSize
; | |
| 374 PrintResults(dictionarySize, encodeTime, benchSize, fals
e, 0); | |
| 375 System.out.print(" "); | |
| 376 PrintResults(dictionarySize, decodeTime, kBufferSize, tr
ue, compressedSize); | |
| 377 System.out.println(); | |
| 378 | |
| 379 totalBenchSize += benchSize; | |
| 380 totalEncodeTime += encodeTime; | |
| 381 totalDecodeTime += decodeTime; | |
| 382 totalCompressedSize += compressedSize; | |
| 383 } | |
| 384 System.out.println("--------------------------------------------
-------"); | |
| 385 PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, fa
lse, 0); | |
| 386 System.out.print(" "); | |
| 387 PrintResults(dictionarySize, totalDecodeTime, | |
| 388 kBufferSize * (long)numIterations, true, totalCo
mpressedSize); | |
| 389 System.out.println(" Average"); | |
| 390 return 0; | |
| 391 } | |
| 392 } | |
| OLD | NEW |