Ruby:优化存储以容纳大量字符串,其中一些是重复的

时间:2016-02-22 08:44:35

标签: ruby algorithm

我有一个包含两列的文本文件。第一列(“键”)中的值都是不同的,第二列中的值 - 这些字符串的长度介于10和大约200之间 - 有一些重复。重复数量各不相同。一些字符串 - 尤其是较长的字符串 - 没有任何重复字符串,而其他字符串可能有20个重复的字符串。

key1  valueX
key2  valueY
key3  valueX
key4  valueZ 

我想将此数据表示为哈希。由于密钥数量众多且存在重复值,我想知道,共享字符串的某种方法是否有用。

文件中的数据有点“常量”,即我可以付出努力(在空间的时间)以适当的方式对其进行预处理,只要它被有效地访问,一旦它进入我的应用程序。 / p>

我现在将概述一种算法,我相信这可以解决问题。 我的问题是,算法是否合理,分别是否可以改进。另外,我想知道在字符串上使用freeze是否会提供额外的优化:

在一个单独的预处理过程中,我找出哪些字符串值确实是重复的,并且我相应地注释数据(即在文件中创建第三列),因为重复的所有出现都是重复的除了第一次出现之外的字符串,有一个指向第一次出现的指针:

key1  valueX
key2  valueY
key3  valueX  key1
key4  valueZ 

当我在我的应用程序中 将数据读入内存(逐行)时,我使用此注释来创建指向原始字符串的指针,而不是分配新的字符串:

if columns.size == 3
  myHash[columns[0]] = columns[1] # First occurance of the string
else
  myHash[columns[0]] = myHash[columns[2]].dup # Subsequent occurances
end

这会实现我的目标吗?可以做得更好吗?

1 个答案:

答案 0 :(得分:0)

你可以这样做的一种方法是使用符号。

["a", "b", "c", "a", "d", "c"].each do |c|
  puts c.intern.object_id
end

417768 #a
313128 #b
312328 #c
417768 #a
433128 #d
312328 #c

注意c是如何得到相同的值。

您可以使用intern方法将字符串转换为符号。如果你实习一个相等的字符串,你应该得到相同的符号,如flyweight pattern

如果您将符号保存在哈希中,那么每个字符串只需一次。在使用符号时,只需在符号上调用.to_s即可获得字符串。 (不确定to_s是如何工作的,它可以在每次调用时进行创建工作。)另一个想法是缓存你自己的字符串,即有一个整数到字符串缓存哈希,只需将整数键放在你的数据结构中。当你需要字符串时,你可以查找它。