tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

LzmaBench.java (9875B)


      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 }