Upload 2.0.2
[physicsfs] / lzma / Java / SevenZip / LzmaBench.java
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)) << 16) ^
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 < BufferSize; 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 inSize)
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, outSizeDe)) / 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, secondSize);
287                 else
288                         rating = GetCompressRating(dictionarySize, elapsedTime, size);
289                 PrintRating(rating);
290         }
291         
292         static public int LzmaBenchmark(int numIterations, int dictionarySize) throws Exception
293         {
294                 if (numIterations <= 0)
295                         return 0;
296                 if (dictionarySize < (1 << 18))
297                 {
298                         System.out.println("\nError: dictionary size for benchmark must be >= 18 (256 KB)");
299                         return 1;
300                 }
301                 System.out.print("\n       Compressing                Decompressing\n\n");
302                 
303                 SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
304                 SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.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) + kCompressedAdditionalSize;
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.BufferSize);
334
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++)
341                 {
342                         progressInfo.Init();
343                         inStream.reset();
344                         compressedStream.reset();
345                         encoder.Code(inStream, compressedStream, -1, -1, progressInfo);
346                         long encodeTime = System.currentTimeMillis() - progressInfo.Time;
347                         
348                         if (i == 0)
349                         {
350                                 compressedSize = compressedStream.size();
351                                 inputCompressedStream = new MyInputStream(compressedBuffer, 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, 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"));
372                         }
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();
378                         
379                         totalBenchSize += benchSize;
380                         totalEncodeTime += encodeTime;
381                         totalDecodeTime += decodeTime;
382                         totalCompressedSize += compressedSize;
383                 }
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");
390                 return 0;
391         }
392 }