【发布时间】:2018-12-03 07:01:03
【问题描述】:
我正在创建一个使用 Huffman 压缩来压缩文件的程序。最初我使用 uint8_t 的向量来存储文件中的字节,但性能很糟糕(解压缩 74 MB 文件需要 2 小时)。 我决定使用 16 位块来表示文件中的值。
最初,我有这个(输入位集有 5.2 亿位)
std::vector<uint8_t> bytes;
boost::dynamic_bitset<unsigned char> input;
boost::to_block_range(input, std::back_inserter(bytes));
这很好用,它填充了一个充满 8 位整数的向量,代表文件的每个字节。每个位的频率都记录在一个大小为 256 的整数向量中。这运行得非常糟糕。解码一个字符串绝对需要永远,因为我的文件中这些整数的频率是巨大的。我认为如果我使用 16 位整数并将频率存储在大小为 65536 的向量中会更好。这是我填充“字节”向量的尝试:
std::vector<uint16_t> bytes;
boost::dynamic_bitset<unsigned char> input;
boost::to_block_range(input, std::back_inserter(bytes));
这里的问题是 to_block_range() 函数从我的位集中取出 8 位并用 8 个零填充它们,而不是一次取出 16 个字节。
有没有办法以这种方式从动态位集中填充 uint16_t 的向量?
【问题讨论】:
-
您是否对代码进行了分析以检查性能问题出在哪里?
-
是的。它发生在每个字节的每个位表示都附加到字符串之后。这个字符串代表了bitset的压缩版本,但是由于只有256个可能的唯一值,这些值的频率是巨大的,这导致字符串是巨大的。要使用霍夫曼解码来解码这个字符串,必须逐个字符地读取它,这需要几个小时
-
huff 解码应该是一个简单而快速的过程,你能更详细地解释一下你在做什么吗?我不明白为什么你的数字频率很大会导致问题。我也不确定我是否理解这里 bitset 的使用,也许你使用了错误的工具来完成这项工作?
-
道歉。我有大量的位集要压缩。我正在将 8 位块读入一个整数(uint8_t)并将所有这些存储在一个向量中。在读入这些内容时,我会增加一个大小为 256 的数组的相应索引(例如,如果我读入 00001010,则索引 10 将增加)。然后,每个字节(共 256 个)都有自己唯一的识别码。更频繁出现的字节获得较短的代码,不太频繁出现的字节获得较长的代码。然后,我通读向量中的每个字节,并将其对应的前缀代码附加到一个字符串中。完成后,该字符串
-
将代表文件的压缩版本。为了解压缩,我必须读取该压缩字符串的每个字符并使用它遍历树以提取原始(解压缩)值。我的问题是,使用 8 位整数意味着对于像我这样大小为 5 亿的位集,0-256 中的每一个数字都会出现成千上万次,从而产生一个巨大的压缩字符串。如果我可以读取 16 个块的位集,我可以有 65536 个不同的值,这意味着我的频率会低得多,压缩的字符串会更小