为什么在 C# 中使用 SharpZipLib 时,压缩后字符串的 GZip 压缩大小大于原始大小
Why am I getting GZip compression size of a string more than the original size after compression when using SharpZipLib in C#
我的字符串是一个 Json 文件 (test.json),其内容如下
{
"objectId": "bbad4cc8-bce8-438e-8683-3e603d746dee",
"timestamp": "2021-04-28T14:02:42.247Z",
"variable": "temperatureArray",
"model": "abc.abcdefg.abcdef",
"quality": 5,
"value": [ 43.471600438222104, 10.00940101687303, 39.925500606152, 32.34369812176735, 33.07786476010357 ]
}
我压缩如下
using ICSharpCode.SharpZipLib.GZip;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
namespace GZipTest
{
public static class SharpZipLibCompression
{
public static void Test()
{
Trace.WriteLine("****************SharpZipLib Test*****************************");
var testFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "test.json");
var text = File.ReadAllText(testFile);
var ipStringSize = System.Text.UTF8Encoding.Unicode.GetByteCount(text);
var compressedString = CompressString(text);
var opStringSize = System.Text.UTF8Encoding.Unicode.GetByteCount(compressedString);
float stringCompressionRatio = (float)opStringSize / ipStringSize;
Trace.WriteLine("String Compression Ratio using SharpZipLib" + stringCompressionRatio);
}
public static string CompressString(string text)
{
if (string.IsNullOrEmpty(text))
return null;
byte[] buffer = Encoding.UTF8.GetBytes(text);
using (var compressedStream = new MemoryStream())
{
GZip.Compress(new MemoryStream(buffer), compressedStream, false);
byte[] compressedData = compressedStream.ToArray();
return Convert.ToBase64String(compressedData);
}
}
}
}
但是我的压缩字符串大小(opStringSize)大于原始字符串大小(ipStringSize)。为什么?
您的基准测试有一些相当基本的问题:
- 您在计算长度时使用 UTF-16 将输入字符串编码为字节(
UTF8Encoding.Unicode
只是一种不明确的写法 Encoding.Unicode
,即 UTF-16)。每个字符编码为 2 个字节,但这些字节中的大部分将为 0。
- 您正在对输出进行 base64 编码。虽然这是一种将任意二进制数据打印为文本的方法,但它使用 4 个字符来表示 3 个字节的数据,因此您将输出的大小增加了 33%。
- 然后您将再次使用 UTF-16 将 base64 编码的字符串转换为字节,每个字符再次占用 2 个字节。所以这是一个人为的 2x 添加到你的结果...
碰巧 UTF-16 的两种用途或多或少抵消了,但 base64 编码位仍然是造成您所看到的许多差异的原因。
把它拿出来,你得到的压缩比是:0.80338985。
考虑到压缩会带来开销,这还不错:有些数据始终需要出现在 GZip 流中,而且无论您的数据压缩得有多好,它都会存在。您只能真正期望压缩对较大的输入产生任何显着差异。
我的字符串是一个 Json 文件 (test.json),其内容如下
{
"objectId": "bbad4cc8-bce8-438e-8683-3e603d746dee",
"timestamp": "2021-04-28T14:02:42.247Z",
"variable": "temperatureArray",
"model": "abc.abcdefg.abcdef",
"quality": 5,
"value": [ 43.471600438222104, 10.00940101687303, 39.925500606152, 32.34369812176735, 33.07786476010357 ]
}
我压缩如下
using ICSharpCode.SharpZipLib.GZip;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
namespace GZipTest
{
public static class SharpZipLibCompression
{
public static void Test()
{
Trace.WriteLine("****************SharpZipLib Test*****************************");
var testFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "test.json");
var text = File.ReadAllText(testFile);
var ipStringSize = System.Text.UTF8Encoding.Unicode.GetByteCount(text);
var compressedString = CompressString(text);
var opStringSize = System.Text.UTF8Encoding.Unicode.GetByteCount(compressedString);
float stringCompressionRatio = (float)opStringSize / ipStringSize;
Trace.WriteLine("String Compression Ratio using SharpZipLib" + stringCompressionRatio);
}
public static string CompressString(string text)
{
if (string.IsNullOrEmpty(text))
return null;
byte[] buffer = Encoding.UTF8.GetBytes(text);
using (var compressedStream = new MemoryStream())
{
GZip.Compress(new MemoryStream(buffer), compressedStream, false);
byte[] compressedData = compressedStream.ToArray();
return Convert.ToBase64String(compressedData);
}
}
}
}
但是我的压缩字符串大小(opStringSize)大于原始字符串大小(ipStringSize)。为什么?
您的基准测试有一些相当基本的问题:
- 您在计算长度时使用 UTF-16 将输入字符串编码为字节(
UTF8Encoding.Unicode
只是一种不明确的写法Encoding.Unicode
,即 UTF-16)。每个字符编码为 2 个字节,但这些字节中的大部分将为 0。 - 您正在对输出进行 base64 编码。虽然这是一种将任意二进制数据打印为文本的方法,但它使用 4 个字符来表示 3 个字节的数据,因此您将输出的大小增加了 33%。
- 然后您将再次使用 UTF-16 将 base64 编码的字符串转换为字节,每个字符再次占用 2 个字节。所以这是一个人为的 2x 添加到你的结果...
碰巧 UTF-16 的两种用途或多或少抵消了,但 base64 编码位仍然是造成您所看到的许多差异的原因。
把它拿出来,你得到的压缩比是:0.80338985。
考虑到压缩会带来开销,这还不错:有些数据始终需要出现在 GZip 流中,而且无论您的数据压缩得有多好,它都会存在。您只能真正期望压缩对较大的输入产生任何显着差异。