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()
19 { A1
= 362436069; A2
= 521288629; }
23 ((A1
= 36969 * (A1
& 0xffff) + (A1
>>> 16)) << 16) ^
24 ((A2
= 18000 * (A2
& 0xffff) + (A2
>>> 16)));
28 static class CBitRandomGenerator
30 CRandomGenerator RG
= new CRandomGenerator();
38 public int GetRnd(int numBits
)
41 if (NumBits
> numBits
)
43 result
= Value
& ((1 << numBits
) - 1);
49 result
= (Value
<< numBits
);
51 result
|= Value
& (((int)1 << numBits
) - 1);
53 NumBits
= 32 - numBits
;
58 static class CBenchRandomGenerator
60 CBitRandomGenerator RG
= new CBitRandomGenerator();
62 public int BufferSize
;
63 public byte[] Buffer
= null;
64 public CBenchRandomGenerator()
68 public void Set(int bufferSize
)
70 Buffer
= new byte[bufferSize
];
72 BufferSize
= bufferSize
;
75 { return RG
.GetRnd(1); }
76 int GetLogRandBits(int numBits
)
78 int len
= RG
.GetRnd(numBits
);
79 return RG
.GetRnd((int)len
);
84 return GetLogRandBits(4);
85 return (GetLogRandBits(4) << 10) | RG
.GetRnd(10);
92 return 4 + RG
.GetRnd(3);
93 return 12 + RG
.GetRnd(4);
95 public void Generate()
97 while (Pos
< BufferSize
)
99 if (GetRndBit() == 0 || Pos
< 1)
100 Buffer
[Pos
++] = (byte)(RG
.GetRnd(8));
103 int offset
= GetOffset();
104 while (offset
>= Pos
)
107 int len
= 2 + GetLen();
108 for (int i
= 0; i
< len
&& Pos
< BufferSize
; i
++, Pos
++)
109 Buffer
[Pos
] = Buffer
[Pos
- offset
];
115 static class CrcOutStream
extends java
.io
.OutputStream
117 public CRC CRC
= new CRC();
123 public int GetDigest()
125 return CRC
.GetDigest();
127 public void write(byte[] b
)
131 public void write(byte[] b
, int off
, int len
)
133 CRC
.Update(b
, off
, len
);
135 public void write(int b
)
141 static class MyOutputStream
extends java
.io
.OutputStream
147 public MyOutputStream(byte[] buffer
)
150 _size
= _buffer
.length
;
158 public void write(int b
) throws IOException
161 throw new IOException("Error");
162 _buffer
[_pos
++] = (byte)b
;
171 static class MyInputStream
extends java
.io
.InputStream
177 public MyInputStream(byte[] buffer
, int size
)
192 return _buffer
[_pos
++] & 0xFF;
196 static class CProgressInfo
implements ICodeProgress
198 public long ApprovedStart
;
203 public void SetProgress(long inSize
, long outSize
)
205 if (inSize
>= ApprovedStart
&& InSize
== 0)
207 Time
= System
.currentTimeMillis();
212 static final int kSubBits
= 8;
214 static int GetLogSize(int size
)
216 for (int i
= kSubBits
; i
< 32; i
++)
217 for (int j
= 0; j
< (1 << kSubBits
); j
++)
218 if (size
<= ((1) << i
) + (j
<< (i
- kSubBits
)))
219 return (i
<< kSubBits
) + j
;
220 return (32 << kSubBits
);
223 static long MyMultDiv64(long value
, long elapsedTime
)
225 long freq
= 1000; // ms
226 long elTime
= elapsedTime
;
227 while (freq
> 1000000)
234 return value
* freq
/ elTime
;
237 static long GetCompressRating(int dictionarySize
, boolean isBT4
, long elapsedTime
, long size
)
239 long numCommandsForOne
;
242 long t
= GetLogSize(dictionarySize
) - (19 << kSubBits
);
243 numCommandsForOne
= 2000 + ((t
* t
* 68) >>> (2 * kSubBits
));
247 long t
= GetLogSize(dictionarySize
) - (15 << kSubBits
);
248 numCommandsForOne
= 1500 + ((t
* t
* 41) >>> (2 * kSubBits
));
250 long numCommands
= (long)(size
) * numCommandsForOne
;
251 return MyMultDiv64(numCommands
, elapsedTime
);
254 static long GetDecompressRating(long elapsedTime
,
255 long outSize
, long inSize
)
257 long numCommands
= inSize
* 250 + outSize
* 21;
258 return MyMultDiv64(numCommands
, elapsedTime
);
261 static long GetTotalRating(
264 long elapsedTimeEn
, long sizeEn
,
266 long inSizeDe
, long outSizeDe
)
268 return (GetCompressRating(dictionarySize
, isBT4
, elapsedTimeEn
, sizeEn
) +
269 GetDecompressRating(elapsedTimeDe
, inSizeDe
, outSizeDe
)) / 2;
272 static void PrintValue(long v
)
276 for (int i
= 0; i
+ s
.length() < 6; i
++)
277 System
.out
.print(" ");
281 static void PrintRating(long rating
)
283 PrintValue(rating
/ 1000000);
284 System
.out
.print(" MIPS");
287 static void PrintResults(
292 boolean decompressMode
, long secondSize
)
294 long speed
= MyMultDiv64(size
, elapsedTime
);
295 PrintValue(speed
/ 1024);
296 System
.out
.print(" KB/s ");
299 rating
= GetDecompressRating(elapsedTime
, size
, secondSize
);
301 rating
= GetCompressRating(dictionarySize
, isBT4
, elapsedTime
, size
);
308 static public int LzmaBenchmark(int numIterations
, int dictionarySize
, boolean isBT4
) throws Exception
310 if (numIterations
<= 0)
312 if (dictionarySize
< (1 << 19) && isBT4
|| dictionarySize
< (1 << 15))
314 System
.out
.println("\nError: dictionary size for benchmark must be >= 19 (512 KB)");
317 System
.out
.print("\n Compressing Decompressing\n\n");
319 SevenZip
.Compression
.LZMA
.Encoder encoder
= new SevenZip
.Compression
.LZMA
.Encoder();
320 SevenZip
.Compression
.LZMA
.Decoder decoder
= new SevenZip
.Compression
.LZMA
.Decoder();
322 if (!encoder
.SetDictionarySize(dictionarySize
))
323 throw new Exception("Incorrect dictionary size");
324 if (!encoder
.SetMatchFinder(isBT4 ?
325 SevenZip
.Compression
.LZMA
.Encoder
.EMatchFinderTypeBT4
:
326 SevenZip
.Compression
.LZMA
.Encoder
.EMatchFinderTypeBT2
))
327 throw new Exception("Incorrect MatchFinder");
329 int kBufferSize
= dictionarySize
+ kAdditionalSize
;
330 int kCompressedBufferSize
= (kBufferSize
/ 2) + kCompressedAdditionalSize
;
332 ByteArrayOutputStream propStream
= new ByteArrayOutputStream();
333 encoder
.WriteCoderProperties(propStream
);
334 byte[] propArray
= propStream
.toByteArray();
335 decoder
.SetDecoderProperties(propArray
);
337 CBenchRandomGenerator rg
= new CBenchRandomGenerator();
344 crc
.Update(rg
.Buffer
, 0, rg
.BufferSize
);
346 CProgressInfo progressInfo
= new CProgressInfo();
347 progressInfo
.ApprovedStart
= dictionarySize
;
349 long totalBenchSize
= 0;
350 long totalEncodeTime
= 0;
351 long totalDecodeTime
= 0;
352 long totalCompressedSize
= 0;
354 MyInputStream inStream
= new MyInputStream(rg
.Buffer
, rg
.BufferSize
);
356 byte[] compressedBuffer
= new byte[kCompressedBufferSize
];
357 MyOutputStream compressedStream
= new MyOutputStream(compressedBuffer
);
358 CrcOutStream crcOutStream
= new CrcOutStream();
359 MyInputStream inputCompressedStream
= null;
360 int compressedSize
= 0;
361 for (int i
= 0; i
< numIterations
; i
++)
365 compressedStream
.reset();
366 encoder
.Code(inStream
, compressedStream
, -1, -1, progressInfo
);
367 long encodeTime
= System
.currentTimeMillis() - progressInfo
.Time
;
371 compressedSize
= compressedStream
.size();
372 inputCompressedStream
= new MyInputStream(compressedBuffer
, compressedSize
);
374 else if (compressedSize
!= compressedStream
.size())
375 throw (new Exception("Encoding error"));
377 if (progressInfo
.InSize
== 0)
378 throw (new Exception("Internal ERROR 1282"));
381 for (int j
= 0; j
< 2; j
++)
383 inputCompressedStream
.reset();
386 long outSize
= kBufferSize
;
387 long startTime
= System
.currentTimeMillis();
388 if (!decoder
.Code(inputCompressedStream
, crcOutStream
, outSize
))
389 throw (new Exception("Decoding Error"));;
390 decodeTime
= System
.currentTimeMillis() - startTime
;
391 if (crcOutStream
.GetDigest() != crc
.GetDigest())
392 throw (new Exception("CRC Error"));
394 long benchSize
= kBufferSize
- (long)progressInfo
.InSize
;
395 PrintResults(dictionarySize
, isBT4
, encodeTime
, benchSize
, false, 0);
396 System
.out
.print(" ");
397 PrintResults(dictionarySize
, isBT4
, decodeTime
, kBufferSize
, true, compressedSize
);
398 System
.out
.println();
400 totalBenchSize
+= benchSize
;
401 totalEncodeTime
+= encodeTime
;
402 totalDecodeTime
+= decodeTime
;
403 totalCompressedSize
+= compressedSize
;
405 System
.out
.println("---------------------------------------------------");
406 PrintResults(dictionarySize
, isBT4
, totalEncodeTime
, totalBenchSize
, false, 0);
407 System
.out
.print(" ");
408 PrintResults(dictionarySize
, isBT4
, totalDecodeTime
,
409 kBufferSize
* (long)numIterations
, true, totalCompressedSize
);
410 System
.out
.println(" Average");