misc/libphysfs/lzma/Java/SevenZip/LzmaBench.java
branchui-scaling
changeset 15283 c4fd2813b127
parent 13390 0135e64c6c66
parent 15279 7ab5cf405686
child 15663 d92eeb468dad
equal deleted inserted replaced
13390:0135e64c6c66 15283:c4fd2813b127
     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 }