使用公共部分压缩字符串

时间:2011-10-13 07:53:23

标签: c++ algorithm compression huffman-code

我有一个管理大量字符串的应用程序。字符串采用类似路径的格式,并且有许多共同的部分,但没有明确的规则。它们不是文件系统上的路径,但可以这样考虑。 我显然需要优化内存消耗,但不会造成很大的性能损失。

我正在考虑两种选择:
- 实现一个compressed_string类来存储压缩的数据,但我需要一个固定的字典,我现在无法找到一个库。我不希望霍夫曼在字节上,我希望它在单词上 - 在字符串部分上实现某种flyweight模式。

这个问题看起来很常见,我想知道什么是最好的解决方案,或者有人知道一个针对这个问题的图书馆。

感谢

2 个答案:

答案 0 :(得分:1)

虽然为您的问题调整特定算法可能很诱人,但可能需要花费不合理的时间和精力,而标准压缩技术将立即为您提供解决内存消耗问题的巨大推动力。

处理此问题的“标准”方法是将源数据块化为小块(例如256KB),并单独压缩它们。将数据访问到块中时,需要先对其进行解码。因此,最佳块大小实际上取决于您的应用程序,即应用程序流越多,块越大;另一方面,随机访问模式越多,块大小越小。

如果您担心压缩/解压缩速度,请使用高速算法。如果解压缩速度是最重要的度量标准(对于访问时间),像LZ4这样的东西将为您提供大约1GB / s的解码性能每个核心,这样您就可以了解每秒可以有多少块解码。

如果只有减压速度很重要,你可以使用高压缩变量LZ4-HC,这将使压缩比提高约30%,同时也提高减压速度。

答案 1 :(得分:0)

  

字符串采用类似路径的格式,并且有许多常见的部分,但没有明确的规则。

从某种意义上说,它们是 name 形式的层次结构,( separator name )*?如果是这样,您可以使用interning:将名称部分存储为指向字符串池的char const *元素。这样,您可以有效地将 n 次使用的名称压缩到超过n * sizeof(char const *) + strlen(name)个字节。完整路径将成为一系列实习名称,例如std::vector

似乎sizeof(char const *)在64位硬件上很大,但您也节省了一些分配开销。或者,如果您因某种原因知道自己永远不会需要超过65536个字符串,那么您可以将它们存储为

class interned_name
{
    uint16_t tab_idx;

  public:
    char const *c_str() const
    {
        return NAME_TABLE[tab_idx];
    }
};

其中NAME_TABLEstatic std::unordered_map<uint16_t, char const *>