All Downloads are FREE. Search and download functionalities are using the official Maven repository.

SevenZip.LzmaBench Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending
 */
package SevenZip;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class LzmaBench {
    static final int kAdditionalSize = (1 << 21);
    static final int kCompressedAdditionalSize = (1 << 10);

    static class CRandomGenerator {
        int A1;
        int A2;

        public CRandomGenerator() {
            Init();
        }

        public void Init() {
            A1 = 362436069;
            A2 = 521288629;
        }

        public int GetRnd() {
            return ((A1 = 36969 * (A1 & 0xffff) + (A1 >>> 16)) << 16) ^
                    ((A2 = 18000 * (A2 & 0xffff) + (A2 >>> 16)));
        }
    };

    static class CBitRandomGenerator {
        CRandomGenerator RG = new CRandomGenerator();
        int Value;
        int NumBits;

        public void Init() {
            Value = 0;
            NumBits = 0;
        }

        public int GetRnd(int numBits) {
            int result;
            if (NumBits > numBits) {
                result = Value & ((1 << numBits) - 1);
                Value >>>= numBits;
                NumBits -= numBits;
                return result;
            }
            numBits -= NumBits;
            result = (Value << numBits);
            Value = RG.GetRnd();
            result |= Value & (((int) 1 << numBits) - 1);
            Value >>>= numBits;
            NumBits = 32 - numBits;
            return result;
        }
    };

    static class CBenchRandomGenerator {
        CBitRandomGenerator RG = new CBitRandomGenerator();
        int Pos;
        int Rep0;

        public int BufferSize;
        public byte[] Buffer = null;

        public CBenchRandomGenerator() {}

        public void Set(int bufferSize) {
            Buffer = new byte[bufferSize];
            Pos = 0;
            BufferSize = bufferSize;
        }

        int GetRndBit() {
            return RG.GetRnd(1);
        }

        int GetLogRandBits(int numBits) {
            int len = RG.GetRnd(numBits);
            return RG.GetRnd((int) len);
        }

        int GetOffset() {
            if (GetRndBit() == 0)
                return GetLogRandBits(4);
            return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
        }

        int GetLen1() {
            return RG.GetRnd(1 + (int) RG.GetRnd(2));
        }

        int GetLen2() {
            return RG.GetRnd(2 + (int) RG.GetRnd(2));
        }

        public void Generate() {
            RG.Init();
            Rep0 = 1;
            while (Pos < BufferSize) {
                if (GetRndBit() == 0 || Pos < 1)
                    Buffer[Pos++] = (byte) (RG.GetRnd(8));
                else {
                    int len;
                    if (RG.GetRnd(3) == 0)
                        len = 1 + GetLen1();
                    else {
                        do
                            Rep0 = GetOffset();
                        while (Rep0 >= Pos);
                        Rep0++;
                        len = 2 + GetLen2();
                    }
                    for (int i = 0; i < len && Pos < BufferSize; i++, Pos++)
                        Buffer[Pos] = Buffer[Pos - Rep0];
                }
            }
        }
    };

    static class CrcOutStream extends java.io.OutputStream {
        public CRC CRC = new CRC();

        public void Init() {
            CRC.Init();
        }

        public int GetDigest() {
            return CRC.GetDigest();
        }

        public void write(byte[] b) {
            CRC.Update(b);
        }

        public void write(byte[] b, int off, int len) {
            CRC.Update(b, off, len);
        }

        public void write(int b) {
            CRC.UpdateByte(b);
        }
    };

    static class MyOutputStream extends java.io.OutputStream {
        byte[] _buffer;
        int _size;
        int _pos;

        public MyOutputStream(byte[] buffer) {
            _buffer = buffer;
            _size = _buffer.length;
        }

        public void reset() {
            _pos = 0;
        }

        public void write(int b) throws IOException {
            if (_pos >= _size)
                throw new IOException("Error");
            _buffer[_pos++] = (byte) b;
        }

        public int size() {
            return _pos;
        }
    };

    static class MyInputStream extends java.io.InputStream {
        byte[] _buffer;
        int _size;
        int _pos;

        public MyInputStream(byte[] buffer, int size) {
            _buffer = buffer;
            _size = size;
        }

        public void reset() {
            _pos = 0;
        }

        public int read() {
            if (_pos >= _size)
                return -1;
            return _buffer[_pos++] & 0xFF;
        }
    };

    static class CProgressInfo implements ICodeProgress {
        public long ApprovedStart;
        public long InSize;
        public long Time;

        public void Init() {
            InSize = 0;
        }

        public void SetProgress(long inSize, long outSize) {
            if (inSize >= ApprovedStart && InSize == 0) {
                Time = System.currentTimeMillis();
                InSize = inSize;
            }
        }
    }

    static final int kSubBits = 8;

    static int GetLogSize(int size) {
        for (int i = kSubBits; i < 32; i++)
            for (int j = 0; j < (1 << kSubBits); j++)
                if (size <= ((1) << i) + (j << (i - kSubBits)))
                    return (i << kSubBits) + j;
        return (32 << kSubBits);
    }

    static long MyMultDiv64(long value, long elapsedTime) {
        long freq = 1000; // ms
        long elTime = elapsedTime;
        while (freq > 1000000) {
            freq >>>= 1;
            elTime >>>= 1;
        }
        if (elTime == 0)
            elTime = 1;
        return value * freq / elTime;
    }

    static long GetCompressRating(int dictionarySize, long elapsedTime, long size) {
        long t = GetLogSize(dictionarySize) - (18 << kSubBits);
        long numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));
        long numCommands = (long) (size) * numCommandsForOne;
        return MyMultDiv64(numCommands, elapsedTime);
    }

    static long GetDecompressRating(long elapsedTime, long outSize, long inSize) {
        long numCommands = inSize * 220 + outSize * 20;
        return MyMultDiv64(numCommands, elapsedTime);
    }

    static long GetTotalRating(
            int dictionarySize,
            long elapsedTimeEn, long sizeEn,
            long elapsedTimeDe,
            long inSizeDe, long outSizeDe) {
        return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +
                GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
    }

    static void PrintValue(long v) {
        String s = "";
        s += v;
        for (int i = 0; i + s.length() < 6; i++)
            System.out.print(" ");
        System.out.print(s);
    }

    static void PrintRating(long rating) {
        PrintValue(rating / 1000000);
        System.out.print(" MIPS");
    }

    static void PrintResults(
            int dictionarySize,
            long elapsedTime,
            long size,
            boolean decompressMode, long secondSize) {
        long speed = MyMultDiv64(size, elapsedTime);
        PrintValue(speed / 1024);
        System.out.print(" KB/s  ");
        long rating;
        if (decompressMode)
            rating = GetDecompressRating(elapsedTime, size, secondSize);
        else
            rating = GetCompressRating(dictionarySize, elapsedTime, size);
        PrintRating(rating);
    }

    static public int LzmaBenchmark(int numIterations, int dictionarySize) throws Exception {
        if (numIterations <= 0)
            return 0;
        if (dictionarySize < (1 << 18)) {
            System.out.println("\nError: dictionary size for benchmark must be >= 18 (256 KB)");
            return 1;
        }
        System.out.print("\n       Compressing                Decompressing\n\n");

        SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
        SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();

        if (!encoder.SetDictionarySize(dictionarySize))
            throw new Exception("Incorrect dictionary size");

        int kBufferSize = dictionarySize + kAdditionalSize;
        int kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;

        ByteArrayOutputStream propStream = new ByteArrayOutputStream();
        encoder.WriteCoderProperties(propStream);
        byte[] propArray = propStream.toByteArray();
        decoder.SetDecoderProperties(propArray);

        CBenchRandomGenerator rg = new CBenchRandomGenerator();

        rg.Set(kBufferSize);
        rg.Generate();
        CRC crc = new CRC();
        crc.Init();
        crc.Update(rg.Buffer, 0, rg.BufferSize);

        CProgressInfo progressInfo = new CProgressInfo();
        progressInfo.ApprovedStart = dictionarySize;

        long totalBenchSize = 0;
        long totalEncodeTime = 0;
        long totalDecodeTime = 0;
        long totalCompressedSize = 0;

        MyInputStream inStream = new MyInputStream(rg.Buffer, rg.BufferSize);

        byte[] compressedBuffer = new byte[kCompressedBufferSize];
        MyOutputStream compressedStream = new MyOutputStream(compressedBuffer);
        CrcOutStream crcOutStream = new CrcOutStream();
        MyInputStream inputCompressedStream = null;
        int compressedSize = 0;
        for (int i = 0; i < numIterations; i++) {
            progressInfo.Init();
            inStream.reset();
            compressedStream.reset();
            encoder.Code(inStream, compressedStream, -1, -1, progressInfo);
            long encodeTime = System.currentTimeMillis() - progressInfo.Time;

            if (i == 0) {
                compressedSize = compressedStream.size();
                inputCompressedStream = new MyInputStream(compressedBuffer, compressedSize);
            } else if (compressedSize != compressedStream.size())
                throw (new Exception("Encoding error"));

            if (progressInfo.InSize == 0)
                throw (new Exception("Internal ERROR 1282"));

            long decodeTime = 0;
            for (int j = 0; j < 2; j++) {
                inputCompressedStream.reset();
                crcOutStream.Init();

                long outSize = kBufferSize;
                long startTime = System.currentTimeMillis();
                if (!decoder.Code(inputCompressedStream, crcOutStream, outSize))
                    throw (new Exception("Decoding Error"));;
                decodeTime = System.currentTimeMillis() - startTime;
                if (crcOutStream.GetDigest() != crc.GetDigest())
                    throw (new Exception("CRC Error"));
            }
            long benchSize = kBufferSize - (long) progressInfo.InSize;
            PrintResults(dictionarySize, encodeTime, benchSize, false, 0);
            System.out.print("     ");
            PrintResults(dictionarySize, decodeTime, kBufferSize, true, compressedSize);
            System.out.println();

            totalBenchSize += benchSize;
            totalEncodeTime += encodeTime;
            totalDecodeTime += decodeTime;
            totalCompressedSize += compressedSize;
        }
        System.out.println("---------------------------------------------------");
        PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);
        System.out.print("     ");
        PrintResults(dictionarySize, totalDecodeTime,
                kBufferSize * (long) numIterations, true, totalCompressedSize);
        System.out.println("    Average");
        return 0;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy