我有一个包含两列的文本文件。第一列(“键”)中的值都是不同的,第二列中的值 - 这些字符串的长度介于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
这会实现我的目标吗?可以做得更好吗?
答案 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是如何工作的,它可以在每次调用时进行创建工作。)另一个想法是缓存你自己的字符串,即有一个整数到字符串缓存哈希,只需将整数键放在你的数据结构中。当你需要字符串时,你可以查找它。