3 import java.io.ByteArrayOutputStream;
4 import java.io.ByteArrayInputStream;
5 import java.io.IOException;
9 static final int kAdditionalSize = (1 << 21);
10 static final int kCompressedAdditionalSize = (1 << 10);
12 static class CRandomGenerator
16 public CRandomGenerator() { Init(); }
17 public void Init() { A1 = 362436069; A2 = 521288629; }
21 ((A1 = 36969 * (A1 & 0xffff) + (A1 >>> 16)) << 16) ^
22 ((A2 = 18000 * (A2 & 0xffff) + (A2 >>> 16)));
26 static class CBitRandomGenerator
28 CRandomGenerator RG = new CRandomGenerator();
36 public int GetRnd(int numBits)
39 if (NumBits > numBits)
41 result = Value & ((1 << numBits) - 1);
47 result = (Value << numBits);
49 result |= Value & (((int)1 << numBits) - 1);
51 NumBits = 32 - numBits;
56 static class CBenchRandomGenerator
58 CBitRandomGenerator RG = new CBitRandomGenerator();
62 public int BufferSize;
63 public byte[] Buffer = null;
65 public CBenchRandomGenerator() { }
66 public void Set(int bufferSize)
68 Buffer = new byte[bufferSize];
70 BufferSize = bufferSize;
72 int GetRndBit() { return RG.GetRnd(1); }
73 int GetLogRandBits(int numBits)
75 int len = RG.GetRnd(numBits);
76 return RG.GetRnd((int)len);
81 return GetLogRandBits(4);
82 return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
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()
90 while (Pos < BufferSize)
92 if (GetRndBit() == 0 || Pos < 1)
93 Buffer[Pos++] = (byte)(RG.GetRnd(8));
97 if (RG.GetRnd(3) == 0)
107 for (int i = 0; i < len && Pos < BufferSize; i++, Pos++)
108 Buffer[Pos] = Buffer[Pos - Rep0];
114 static class CrcOutStream extends java.io.OutputStream
116 public CRC CRC = new CRC();
122 public int GetDigest()
124 return CRC.GetDigest();
126 public void write(byte[] b)
130 public void write(byte[] b, int off, int len)
132 CRC.Update(b, off, len);
134 public void write(int b)
140 static class MyOutputStream extends java.io.OutputStream
146 public MyOutputStream(byte[] buffer)
149 _size = _buffer.length;
157 public void write(int b) throws IOException
160 throw new IOException("Error");
161 _buffer[_pos++] = (byte)b;
170 static class MyInputStream extends java.io.InputStream
176 public MyInputStream(byte[] buffer, int size)
191 return _buffer[_pos++] & 0xFF;
195 static class CProgressInfo implements ICodeProgress
197 public long ApprovedStart;
202 public void SetProgress(long inSize, long outSize)
204 if (inSize >= ApprovedStart && InSize == 0)
206 Time = System.currentTimeMillis();
211 static final int kSubBits = 8;
213 static int GetLogSize(int size)
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);
222 static long MyMultDiv64(long value, long elapsedTime)
224 long freq = 1000; // ms
225 long elTime = elapsedTime;
226 while (freq > 1000000)
233 return value * freq / elTime;
236 static long GetCompressRating(int dictionarySize, long elapsedTime, long size)
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);
244 static long GetDecompressRating(long elapsedTime, long outSize, long inSize)
246 long numCommands = inSize * 220 + outSize * 20;
247 return MyMultDiv64(numCommands, elapsedTime);
250 static long GetTotalRating(
252 long elapsedTimeEn, long sizeEn,
254 long inSizeDe, long outSizeDe)
256 return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +
257 GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
260 static void PrintValue(long v)
264 for (int i = 0; i + s.length() < 6; i++)
265 System.out.print(" ");
269 static void PrintRating(long rating)
271 PrintValue(rating / 1000000);
272 System.out.print(" MIPS");
275 static void PrintResults(
279 boolean decompressMode, long secondSize)
281 long speed = MyMultDiv64(size, elapsedTime);
282 PrintValue(speed / 1024);
283 System.out.print(" KB/s ");
286 rating = GetDecompressRating(elapsedTime, size, secondSize);
288 rating = GetCompressRating(dictionarySize, elapsedTime, size);
292 static public int LzmaBenchmark(int numIterations, int dictionarySize) throws Exception
294 if (numIterations <= 0)
296 if (dictionarySize < (1 << 18))
298 System.out.println("\nError: dictionary size for benchmark must be >= 18 (256 KB)");
301 System.out.print("\n Compressing Decompressing\n\n");
303 SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
304 SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
306 if (!encoder.SetDictionarySize(dictionarySize))
307 throw new Exception("Incorrect dictionary size");
309 int kBufferSize = dictionarySize + kAdditionalSize;
310 int kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
312 ByteArrayOutputStream propStream = new ByteArrayOutputStream();
313 encoder.WriteCoderProperties(propStream);
314 byte[] propArray = propStream.toByteArray();
315 decoder.SetDecoderProperties(propArray);
317 CBenchRandomGenerator rg = new CBenchRandomGenerator();
323 crc.Update(rg.Buffer, 0, rg.BufferSize);
325 CProgressInfo progressInfo = new CProgressInfo();
326 progressInfo.ApprovedStart = dictionarySize;
328 long totalBenchSize = 0;
329 long totalEncodeTime = 0;
330 long totalDecodeTime = 0;
331 long totalCompressedSize = 0;
333 MyInputStream inStream = new MyInputStream(rg.Buffer, rg.BufferSize);
335 byte[] compressedBuffer = new byte[kCompressedBufferSize];
336 MyOutputStream compressedStream = new MyOutputStream(compressedBuffer);
337 CrcOutStream crcOutStream = new CrcOutStream();
338 MyInputStream inputCompressedStream = null;
339 int compressedSize = 0;
340 for (int i = 0; i < numIterations; i++)
344 compressedStream.reset();
345 encoder.Code(inStream, compressedStream, -1, -1, progressInfo);
346 long encodeTime = System.currentTimeMillis() - progressInfo.Time;
350 compressedSize = compressedStream.size();
351 inputCompressedStream = new MyInputStream(compressedBuffer, compressedSize);
353 else if (compressedSize != compressedStream.size())
354 throw (new Exception("Encoding error"));
356 if (progressInfo.InSize == 0)
357 throw (new Exception("Internal ERROR 1282"));
360 for (int j = 0; j < 2; j++)
362 inputCompressedStream.reset();
365 long outSize = kBufferSize;
366 long startTime = System.currentTimeMillis();
367 if (!decoder.Code(inputCompressedStream, crcOutStream, outSize))
368 throw (new Exception("Decoding Error"));;
369 decodeTime = System.currentTimeMillis() - startTime;
370 if (crcOutStream.GetDigest() != crc.GetDigest())
371 throw (new Exception("CRC Error"));
373 long benchSize = kBufferSize - (long)progressInfo.InSize;
374 PrintResults(dictionarySize, encodeTime, benchSize, false, 0);
375 System.out.print(" ");
376 PrintResults(dictionarySize, decodeTime, kBufferSize, true, compressedSize);
377 System.out.println();
379 totalBenchSize += benchSize;
380 totalEncodeTime += encodeTime;
381 totalDecodeTime += decodeTime;
382 totalCompressedSize += compressedSize;
384 System.out.println("---------------------------------------------------");
385 PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);
386 System.out.print(" ");
387 PrintResults(dictionarySize, totalDecodeTime,
388 kBufferSize * (long)numIterations, true, totalCompressedSize);
389 System.out.println(" Average");