当前位置: 首页 > 面试题库 >

在大型文本文件中搜索字符串-在python中分析各种方法

谢翰学
2023-03-14
问题内容

这个问题已经被问过很多次了。花了一些时间阅读答案之后,我进行了一些简要的分析,以尝试前面提到的各种方法…

  • 我有一个 600 MB的 文件,其中包含 600万 行字符串(来自DMOZ项目的类别路径)。
  • 每行上的条目都是唯一的。
  • 我想 一次* 加载 文件并 继续在 数据中 搜索 匹配项 ***

我在下面尝试的三种方法列出了加载文件所需的时间,任务管理器中 负匹配的 搜索时间和内存使用情况

1) set :
    (i)  data   = set(f.read().splitlines())
    (ii) result = search_str in data

加载时间〜10s,搜索时间〜0.0s,内存使用量〜1.2GB

2) list :
    (i)  data   = f.read().splitlines()
    (ii) result = search_str in data

加载时间〜6s,搜索时间〜0.36s,内存使用量〜1.2GB

3) mmap :
    (i)  data   = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
    (ii) result = data.find(search_str)

加载时间〜0s,搜索时间〜5.4s,内存使用率〜NA

4) Hash lookup (using code from @alienhard below):

加载时间〜65s,搜索时间〜0.0s,内存使用量〜250MB

5) File search (using code from @EOL below):   
   with open('input.txt') as f:
       print search_str in f #search_str ends with the ('\n' or '\r\n') as in the file

加载时间〜0s,搜索时间〜3.2s,内存使用率〜NA

6) sqlite (with primary index on url):

加载时间〜0s,搜索时间〜0.0s,内存使用率〜NA

对于我的用例,只要我有足够的可用内存,似乎最好使用该设置。我希望对这些问题发表一些评论:

  1. 一个 更好的替代品, 例如sqlite?
  2. 的方式来 使用mmap改善搜索时间 。我有一个64位安装程序。[编辑]例如绽放过滤器
  3. 随着文件大小增加到几GB,我有什么办法可以继续使用“设置”,例如,将其分成几批..

[编辑1] PS我需要经常搜索,添加/删除值,并且不能单独使用哈希表,因为稍后需要检索修改后的值。

欢迎任何意见/建议!

[edit 2]更新答案中建议的方法的结果[edit 3]更新sqlite结果

解决方案
:基于所有分析和费用分摊,我认为我将使用sqlite。第二种选择是方法4。sqlite的缺点是数据库大小是带有url的原始csv文件的两倍多。这是由于url上的主索引


问题答案:

如果您需要启动许多顺序搜索,则变式1非常有用。由于set在内部是哈希表,因此在搜索中相当不错。但是,构建需要花费时间,并且只有在您的数据适合RAM的情况下才能正常工作。

变体3适用于非常大的文件,因为您有足够的地址空间来映射它们,并且OS缓存了足够的数据。您进行全面扫描;一旦您的数据停止装入RAM,它就会变得相当慢。

如果您需要在行中进行多次搜索并且无法将数据放入RAM中,则SQLite绝对是一个好主意。将字符串加载到表中,构建索引,然后SQLite为您构建一个漂亮的b树。即使没有数据,树也可以放入RAM中(有点像@alienhard提出的内容),即使没有,也可以大大减少I
/ O所需的数量。当然,您需要创建一个基于磁盘的SQLite数据库。我怀疑基于内存的SQLite是否会明显击败Variant 1。



 类似资料:
  • 问题内容: 我需要在一个很大的文本文件中搜索特定的字符串。它的构建日志包含大约5000行文本。最好的方法是什么?使用正则表达式应该不会引起任何问题吗?我将继续阅读几行,并使用简单的查找。 问题答案: 如果它是“相当大”的文件,请顺序访问各行,而不要将整个文件读入内存:

  • 问题内容: 我想检查字符串是否在文本文件中。如果是,请执行X。否则,请执行Y。但是,True由于某些原因,此代码始终返回。谁能看到错在哪里? 问题答案: 你一直得到的原因已经给出,因此我只提供另一个建议: 如果你的文件不是太大,则可以将其读取为字符串,然后使用它(比读取和检查每行更容易,并且通常更快): 另一个技巧:通过使用创建使用基础文件的“字符串状”对象(而不是读取内存中的整个文件),可以减轻

  • 问题内容: 我有mysql表,其中有一列将xml存储为字符串。我需要找到xml列包含给定6个字符的字符串的所有元组。没关系-我只需要知道这6个字符串是否存在即可。 因此,将文本格式设置为xml可能并不重要。 问题:如何在mysql中搜索?即 有没有一种方法可以使用LIKE运算符执行此操作? 问题答案: 您可能可以使用该子句进行一些简单的字符串匹配: 如果您需要更多高级功能,请在此处查看MySQL的

  • 我试图创建一个java程序,它可以读取一个名为file1.txt的文件,存储它的字符串,并将这些字符串搜索到另一个名为file2.txt的文件,如果没有找到匹配,则从file1.txt打印特定的字符串。 现在我可以从file1.txt获得数据,但无法搜索file1的数据,例如在file2.txt中搜索单词“home” 请看这里的file1.txt包含Homee,而file2.txt有Home,所以

  • 问题内容: 我正在寻找将某些字符串搜索到某些文件夹结构中的最快方法。我知道可以使用file_get_contents从文件中获取所有内容,但是我不确定是否很快。也许已经有一些可以快速运行的解决方案。我正在考虑使用scandir获取所有文件,并使用file_get_contents读取其内容,并使用strpos来检查字符串是否存在。 您认为这样做有更好的方法吗? 或者也许试图与grep一起使用php

  • 如果我搜索John,就会得到结果(如果我搜索Jo,就会得到event)。但如果我搜索无名氏,显然没有任何结果。 如果我将查询更改为JohnDoe,我会得到结果,但它会返回所有在其最后/名字中有John或Doe的人。 接下来是尝试使用mongoose TextSearch: 有办法解决吗? 没有外部插件的答案是首选的,但其他的也是希望的。