首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >快捷和管理的压缩性能差异(c#)

快捷和管理的压缩性能差异(c#)
EN

Stack Overflow用户
提问于 2022-03-22 08:56:58
回答 1查看 124关注 0票数 2

我正在托管内存环境中实现LZF压缩,并从ios环境中解压缩。

这就是我在c#中实现lzf解压缩的代码

代码语言:javascript
复制
private static int LZFDecompress(byte[] input, byte[] output)
{
    int inputLength = input.Length;
    int outputLength = output.Length;

    uint iidx = 0;
    uint oidx = 0;

    do
    {
        uint ctrl = input[iidx++];

        if (ctrl < (1 << 5)) /* literal run */
        {
            ctrl++;

            if (oidx + ctrl > outputLength)
            {
                //SET_ERRNO (E2BIG);
                return 0;
            }

            do
                output[oidx++] = input[iidx++];
            while ((--ctrl) != 0);
        }
        else /* back reference */
        {
            uint len = ctrl >> 5;

            int reference = (int)(oidx - ((ctrl & 0x1f) << 8) - 1);

            if (len == 7)
                len += input[iidx++];

            reference -= input[iidx++];

            if (oidx + len + 2 > outputLength)
            {
                //SET_ERRNO (E2BIG);
                return 0;
            }

            if (reference < 0)
            {
                //SET_ERRNO (EINVAL);
                return 0;
            }

            output[oidx++] = output[reference++];
            output[oidx++] = output[reference++];

            do
                output[oidx++] = output[reference++];
            while ((--len) != 0);
        }
    }
    while (iidx < inputLength);

    return (int)oidx;
}

像这样移植到斯威夫特

代码语言:javascript
复制
    private static func LZFDecompress(input: [UInt8],
                                      output: inout [UInt8])
        -> Int
    {
        let inputLength = input.count
        let outputLength = output.count
        
        var iidx = 0
        var oidx = 0
        
        repeat
        {
            var ctrl = Int(input[iidx])
            iidx += 1
            
            if ctrl < (1 << 5)
            {
                ctrl += 1
                
                if oidx + ctrl > outputLength
                {
                    return 0
                }
                
                repeat
                {
                    output[oidx] = input[iidx]
                    oidx += 1
                    iidx += 1
                    ctrl -= 1
                }
                while ctrl != 0
            }
            else
            {
                var len = ctrl >> 5
                var reference = oidx - ((ctrl & 0x1f) << 8) - 1
                
                if len == 7
                {
                    len += Int(input[iidx])
                    iidx += 1
                }
                
                reference -= Int(input[iidx])
                iidx += 1
                
                if oidx + len + 2 > outputLength
                {
                    return 0
                }
                
                if reference < 0
                {
                    return 0
                }
                
                output[oidx] = output[reference]
                oidx += 1
                reference += 1
                output[oidx] = output[reference]
                oidx += 1
                reference += 1
                
                repeat
                {
                    output[oidx] = output[reference]
                    oidx += 1
                    reference += 1
                    len -= 1
                }
                while len != 0
            }
        }
        while iidx < inputLength
        
        return oidx
    }

但我有一个问题,这是一个表现上的差异。在c#中需要2-3秒,但是要快速解压缩相同的文件要花费9-10秒.我无法理解这种情况。

我在windows的控制台上测试了c#。我测试了斯威夫特在操场或在mac的项目。

EN

回答 1

Stack Overflow用户

发布于 2022-03-24 02:10:04

这不是没有考虑到SIMD和CPU的有效代码。因此,我使用的解压缩方法(lz4,zlib)是由苹果提供的。比以前快多了。它的成本低于1秒解压缩200 It文件。

但是在托管环境(c#)中,它比非托管环境慢。如果您希望获得更多的性能,请实现本机。

我使用这些lzib托管代码。

解压缩需要6-7秒,在同一个文件上压缩需要30秒.

然后你应该知道这个代码与苹果的lzip兼容。它包括为压缩数据添加报头。

代码语言:javascript
复制
    public static byte[] Compress(byte[] inputData)
    {
        var zlib = new ZlibCodec(CompressionMode.Compress);
        zlib.CompressLevel = Zlib.CompressionLevel.AppleSupported; // Level5
        zlib.InputBuffer = inputData;
        zlib.OutputBuffer = new byte[inputData.Length];
        zlib.NextIn = 0;
        zlib.AvailableBytesIn = inputData.Length;
        zlib.NextOut = 0;
        zlib.AvailableBytesOut = inputData.Length;
        zlib.InitializeDeflate(Zlib.CompressionLevel.AppleSupported, false); 
        // 'false' means it's 1951(deflate) version not 1950(lzib) version
        zlib.Deflate(FlushType.Finish);
        var output = new byte[zlib.TotalBytesOut];
        Array.Copy(zlib.OutputBuffer, output, (int)zlib.TotalBytesOut);
        return output;
    }

    public static byte[] Decompress(byte[] inputData, int outputSize)
    {
        var zlib = new ZlibCodec(CompressionMode.Decompress);
        zlib.CompressLevel = Zlib.CompressionLevel.AppleSupported;
        zlib.InputBuffer = inputData;
        zlib.OutputBuffer = new byte[outputSize];
        zlib.NextIn = 0;
        zlib.AvailableBytesIn = inputData.Length;
        zlib.NextOut = 0;
        zlib.AvailableBytesOut = outputSize;
        zlib.InitializeInflate(false);
        zlib.Inflate(FlushType.Finish);
        var output = new byte[zlib.TotalBytesOut];
        Array.Copy(zlib.OutputBuffer, output, (int)zlib.TotalBytesOut);
        return output;
    }

我希望帮助像我这样的人实现多平台压缩。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71569303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档