gpt4 book ai didi

python - Unix 目录结构的快速、逐行 "grep -n"等价物

转载 作者:太空狗 更新时间:2023-10-29 21:04:05 26 4
gpt4 key购买 nike

我正在尝试创建一个网络界面来搜索大量巨大的配置文件(大约 60000 个文件,每个文件的大小在 20 KB 到 50 MB 之间)。这些文件也经常更新(~3 次/天)。

要求:

  • 并发
  • 必须确定每个匹配行的行号
  • 良好的更新性能

我调查的内容:

  • Lucene:要标识行号,每一行必须存储在单独的 Lucene 文档中,每个文档包含两个字段(行号和行)。这会使更新变得困难/缓慢。
  • SOLRSphinx:都是基于Lucene,他们有同样的问题,不能识别行号。
  • 带全文索引的 SQL 表:同样,无法显示行号。
  • 每行单独一行的 SQL 表:使用 SQLite 或 MySQL 对此进行了测试,更新性能是所有选项中最差的。更新一个 50 MB 的文档需要一个多小时。
  • eXist-db:我们将每个文本文件转换为 XML,如下所示:<xml><line number="1">test</line>...</xml> .更新大约需要 5 分钟,这有点管用,但我们仍然对此不满意。
  • Whoosh 用于 Python:非常类似于 Lucene。我已经实现了一个原型(prototype),它通过删除/重新导入给定文件的所有行来工作。使用此方法更新 50MB 的文档大约需要 2-3 分钟。
  • GNU id utils:由 sarnold 建议,这非常快(50MB 文档在我的测试机器上更新不到 10 秒),如果它有分页和 API 就完美了。

您将如何实现替代方案?

最佳答案

您可能希望调查 GNU idutils工具包。在 Linux 内核源代码的本地副本上,它可以提供如下输出:

$ gid ugly
include/linux/hil_mlc.h:66: * a positive return value causes the "ugly" branch to be taken.
include/linux/hil_mlc.h:101: int ugly; /* Node to jump to on timeout */

从冷缓存重建索引相当快:

$ time mkid

real 1m33.022s
user 0m17.360s
sys 0m2.730s

从热缓存重建索引要快得多:

$ time mkid

real 0m15.692s
user 0m15.070s
sys 0m0.520s

对于我的 2.1 GB 数据,该索引仅占用 46 兆字节 -- 与您的数据相比很小,但这个比率感觉不错。

找到 399 次 foo 只用了 0.039 秒:

$ time gid foo > /dev/null

real 0m0.038s
user 0m0.030s
sys 0m0.000s

更新

Larsmans 很好奇 git grep 在内核源代码上的性能——这是显示 gid(1) 提供了多少性能增益的极好方式。

在冷缓存上,git grep foo(返回 1656 个条目,远远超过 idutils):

$ time git grep foo > /dev/null

real 0m19.231s
user 0m1.480s
sys 0m0.680s

一旦缓存变暖,git grep foo 运行得更快:

$ time git grep foo > /dev/null

real 0m0.264s
user 0m1.320s
sys 0m0.330s

因为一旦缓存变暖,我的数据集就完全适合 RAM,git grep 非常惊人:它只比 gid(1) 实用程序慢七倍,当然对于交互式使用来说,它的速度已经足够快了。如果所讨论的数据集不能完全缓存(这可能是事情真正变得有趣的地方),那么索引的性能优势是显而易见的。

关于idutils的两个提示:

  1. 没有分页。这绝对是一个缺点,尽管根据我的经验,它运行得足够快,可以简单地将搜索结果存储在别处。如果搜索要返回原始数据集的可观百分比,那么存储部分结果肯定会很烦人。

  2. 没有 API:没错,没有 API。但是来源是可用的; src/lid.c 函数 report_grep() 获取与输出匹配的文件链接列表。稍微摆弄一下这个功能甚至可以提供分页功能。 (这需要做一些工作。)最终,您将拥有一个 C API,但它可能仍然不理想。但自定义它看起来并不糟糕。

然而,最糟糕的弱点可能是缺少增量数据库更新。如果所有 文件每天更新​​三次,这没什么大不了的。如果一些 文件一天更新三次,它就是在做不必要的工作。如果一天三次更新少数文件,则必须有更好的解决方案。

关于python - Unix 目录结构的快速、逐行 "grep -n"等价物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8121142/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com