上下文:我正在编写一些东西来处理日志数据,这涉及将几GB数据加载到内存中并交叉检查各种内容,查找数据中的相关性并将结果写入另一个文件。 (这实际上是在加载到Druid.io集群之前的烹饪/非规范化步骤。)我想避免为了性能和代码简单性而将信息写入数据库 - 假设在可预见的将来数据量可以通过向机器添加内存来处理一次处理。
我的问题是,尝试在我的代码中明确重复删除字符串是否是一个好主意;如果是这样,什么是好方法。这些日志文件中的许多值都是完全相同的文本(可能文件中大约25%的文本值是唯一的粗略猜测)。
由于我们正在谈论数据的演出,虽然ram很便宜并且可以进行交换,但仍有一个限制,如果我不小心,我很可能会遇到它。如果我做这样的事情:
strstore := make(map[string]string)
// do some work that involves slicing and dicing some text, resulting in:
var a = "some string that we figured out that has about a 75% chance of being duplicate"
// note that there are about 10 other such variables that are calculated here, only "a" shown for simplicity
if _, ok := strstore[a]; !ok {
strstore[a] = a
} else {
a = strstore[a]
}
// now do some more stuff with "a" and keep it in a struct which is in
// some map some place
在我看来,这会产生"重复使用"现有字符串,以哈希查找和比较为代价。看似很好的交易。
但是,如果实际上是new的字符串导致内存碎片化并且有多个无法声明的漏洞,那么这可能没那么有用。
我还可以尝试保留一个具有字符数据和索引的大字节数组/切片,但这会使代码难以编写(尤其是必须在[]字节和字符串之间进行转换,涉及它自己的分配)我可能只是做了一个非常糟糕的工作,实际上是Go运行时的域。
寻找有关解决此问题的方法的任何建议,或者如果任何人对此类事情的经验产生了特别有用的机制来解决这个问题。
答案 0 :(得分:1)
您可以在此处使用许多有趣的数据结构和算法。这取决于你在统计和处理阶段所做的尝试。
我不确定您的日志是否可压缩,但您可以根据用例情况预处理数据:https://github.com/alecthomas/mph/blob/master/README.md
看看其中一些数据结构以及背景: