我有这个文本文件包含一些md5哈希,其中有1亿行。我有另一个较小的文件,有几千md5哈希。我想从这个新的较小文件中找到这些md5哈希的相应索引到旧的较大文件。
最有效的方法是什么?可以在15分钟左右的时间内完成吗?
我尝试了很多东西,但它们不起作用。首先,我尝试将较大的数据导入数据库文件,并在md5哈希列上创建索引。创建此哈希需要永远。我甚至不确定这是否会提高查询速度。建议?
答案 0 :(得分:3)
请勿在db中执行此操作 - 使用简单程序。
哈希映射中的平均查找时间应该接近 O(1),所以这个的处理时间基本上有多快可以阅读大文件。
使用这种方法,今天的硬件很容易获得15分钟。
答案 1 :(得分:1)
首先:100Megarowsà32Bytes = ca. 3.2 GByte数据。在15分钟内读取它们可转换为每秒3.5兆字节,这对于现代硬件来说应该很容易实现。
我建议不来使用数据库,但过程包含一些简单的步骤:
初始排序可能需要超过15分钟,但查找应该非常快:如果你有足够的RAM(以及支持大于2GB的进程的操作系统),你应该能够获得至少一个比较率数量级更快!
答案 2 :(得分:0)
有专门设计用于在大文件中搜索多个字符串的算法。其中一个是Rabin-Karp。我有blog post about this。
更简单地说,以下伪代码应该立即让你到那里:
Load your few thousand strings in a set data structure
For each line (index: i) in your file
If that line appears in your set of values
print i
这将非常快:设置的数据结构几乎是即时查找,因此IO将成为罪魁祸首,1亿个hashsums将在15分钟内完成,没有太多困难。
答案 3 :(得分:0)
假设:
(1)小文件中的每条记录都出现在大文件中
(2)每个文件中的数据是随机排序的。
选项:
(1)对于大文件中的每个记录,线性搜索小文件以进行匹配。由于大多数搜索都找不到匹配项,因此时间将接近 Nlarge * Nsmall * k 其中k表示尝试一场比赛的时间。
(2)对于小文件中的每个记录,线性搜索大文件以查找匹配项。由于每次搜索都会找到一个匹配项,因此时间会很长 Nlarge / 2 * Nsmall * k。
这看起来比选项(1)快两倍 - 但前提是你可以将大文件完全放入快速内存中。您可能需要6 GB的RAM。
(3)将小文件分类为易于搜索的形式。平衡的二叉树是最好的,但排序的数组几乎一样好。或者你可以相信一些方便的哈希表对象的作者在CS学校受到关注。对于大文件中的每个记录,搜索结构化小文件以查找匹配项。时间会是 log2 Nsmall * s 对小文件进行排序,其中s表示对一条记录进行排序的时间,加上 log2 Nsmall * Nlarge * k 用于扫描。这给出了总时间 log2 Nsmall *(s + Nlarge * k)。
(4)将大文件排序为易于搜索的形式。对于小文件中的每个记录,搜索结构化大文件以查找匹配项。时间会是 log2 Nlarge * s 排序大文件加 log2 Nlarge * Nsmall * k 对于扫描,总共给出了 log2 Nlarge *(s + Nsmall * k)。
选项(4)显然是最快的,因为减少任何系数的Nlarge支配所有其他改进。但是,如果从大文件派生的可排序结构不能完全适合RAM,那么选项(3)可能会变得更快。
(5)将大文件分类为易于搜索的形式。将此结构分解为适合您的RAM的部分。对于每个这样的片段,将片段加载到RAM中,然后对于小文件中的每个记录,搜索当前加载的片段以进行匹配。时间会是 log2 Nlarge * s 排序大文件加 log2 Nlarge * Nsmall * k * p 对于扫描,结构被分成p个部分,总共给出了 log2 Nlarge *(s + Nsmall * k * p)。
使用您为Nlarge和Nsmall指示的值,以及足够的RAM以便p可以保持为单个数字,选项(5)似乎可能是最快的。