代码之家  ›  专栏  ›  技术社区  ›  Faraz

编码字符串会占用更少的内存吗?

  •  1
  • Faraz  · 技术社区  · 6 年前

    我对记忆空间的话题感到困惑。假设我们有以下字符串:

    String from = "Hello I am from Chicago";
    

    如果我使用哈夫曼编码、LZ4或Gzip等对其进行编码(此时编码算法无关紧要):

    String encodedFrom= encodingLibrary.encode(from);
    

    现在,内存空间的数量 encodedName 会坚持,会比什么都少 name 会被带走吗?

    我很困惑,因为当我们存储字符串时,即使有更少的位,vm(或操作系统本身,或其他东西)也会在末尾添加填充以完成字节。像那样。所以在一天结束时,对于编码的和 联合国 -编码字符串。我这样认为对吗?

    第二个问题和第一个问题有关,我实际上想编码100条成千上万的记录,并将其存储在redis缓存中。如果我们排除压缩/解压和内存消耗因素所需的时间,这将如何发挥作用?编码字符串在redis缓存中占用的空间会更少?

    感谢任何帮助。

    1 回复  |  直到 6 年前
        1
  •  4
  •   Roland Illig    6 年前

    压缩一个字符串,然后将压缩结果存储回另一个字符串是一个非常糟糕的主意。

    按照惯例,字符串是字符序列。它们应该包含字母、标点、空格和类似的内容。任何人发现你用它们存储二进制数据都会对你生气,因为这是非常不寻常的。

    如果要压缩字符串,请尽可能诚实,并将压缩数据存储在字节数组中。字节数组是通用容器,应该在其中存储任意数据。

    回到你的主要问题。在Java中 String 基本上是 char[] ,这意味着每个字符消耗16位(就处理纯英语或其他来自 Basic Multilingual Plane )

    因为您的所有字符都是ASCII码,所以每个字符都可以使用7位进行编码。在最前面再加一个位,说“这个字符串的其余部分仅限于ASCII”,最后得到一个简单的压缩方案,然后 1 + 23 * 7 位,相当于21个字节。当然,在本例中,最后一个字节中有6位填充,但是与 2 * 23 按原样存储字符串的字节数,这已经很好了。

    (我刚刚忘记:自从Java 9,ASCII只有字符串以一种特殊的方式存储,每个字符只使用8位,而不是使用16位。因此,上面提到的压缩方案只在Java 8之前才有效。

    当使用redis进行数据存储时,请记住,它将所有数据保存在RAM中,一旦无法分配更多的RAM,就会崩溃。(据我所知,这是大约5年前的事了。)因此,如果您已经可以估计Redis数据将超过几GB,那么最好选择另一个数据存储库。