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 |