【问题标题】:Python: Improving sub-string search by embedding sophisticated algorithmsPython:通过嵌入复杂算法改进子字符串搜索
【发布时间】:2012-08-28 20:08:48
【问题描述】:

我正在扩展我之前的问题python efficient substring search

我有兴趣提高子字符串搜索实现的性能,

我上一个问题的一些答案指出,子字符串搜索是通过使用受 B-M 算法启发的 fastsearch 来实现的, 这是source code

更多答案将我指向 Boyer-Moore 算法、Rabin-Karp 算法的 python 实现。

使用这些算法(B-M,Rabin-Karp)嵌入 c 代码作为子字符串搜索的良好实现是否有效?

【问题讨论】:

  • @MartijnPieters:这是一个答案,贴出来!
  • 通常你使用 C 代码(非嵌入)扩展 Python,例如,使用Cython(你不需要创建扩展模块的权限)。 100 次似乎也不错。你测试过代码吗?您是否尝试过在大字符串的开始/中间/结束/缺失时测量单词的性能(假设您的算法目标是在大字符串上使用)。这是一个如何优化 Python 的示例:Simple Python Challenge: Fastest Bitwise XOR on Data Buffers
  • 我已阅读您的 RabinKarp 代码,但它不正确。如果 h==h256 其中 h, h256 只有 256 个不同的值,则返回 true。嵌套循环什么都不做。
  • 仔细阅读代码。 continue 推进内部循环。它对外部循环没有任何作用。
  • @J.F. Sebastian:谢谢,你说得对,我现在就修复它并再次编辑所有内容,

标签: python c performance algorithm substring


【解决方案1】:

您没有具体说明“高效”的含义。你愿意做出哪些取舍?在初始化新字符串时,您是否准备为性能损失付出代价?什么时候开始搜索?你会用更多的内存换取更快的速度吗?

python开发者在开发python字符串库时设置clear goals

  • 对于所有测试用例(基于真实代码),包括 Jim Hugunin 的最坏情况测试,都应该比当前的蛮力算法更快
  • 小设置开销;快速路径中没有动态分配(速度为 O(m),存储为 O(1))
  • 良好情况下的次线性搜索行为 (O(n/m))
  • 在最坏情况下不比当前算法差 (O(nm))
  • 应该适用于 8 位字符串和 16 位或 32 位 Unicode 字符串(无 O(σ) 依赖性)
  • 许多现实生活中的搜索应该是好的,极少数应该是最坏的情况
  • 相当简单的实现

因此,开发人员对搜索案例和设置案例的性能、存储要求以及维护效率设置了一些限制。这些边界排除了 Boyer-Moore(因为它需要对搜索的字符串进行预处理、启动成本和存储成本),虽然我没有看到开发人员考虑过 Rabin-Karp 的证据,但它可以被排除在同一个理由(您需要创建哈希并存储这些)。

界限是基于 很多 python 内部结构和使用经验设置的。上面的总结不是凭空捏造的,只是对那次经历的总结。

现在,如果您有一个特定的情况,您的权衡可以设置不同,那么可以肯定的是,不同算法的 C 实现可以很好地击败标准 Python 实现。但根据不同的一组标准,它会更有效。

无论如何,Python 搜索算法都会处理小字符串的情况。如果您尝试将其应用于 正文,则算法的性能将无法与做出适用于大文本的不同选择的算法一样好。如果你必须在 10,000,000 个文档中搜索文本,你会想要使用某种索引解决方案,而不是微不足道的 Python 字符串搜索。

将其与使用默认排序实现对 100 个项目的列表进行排序相比,与对 10,000,000,000 个整数进行排序进行比较。在后一种情况下,有一些排序实现可以轻松击败默认的 Python 产品。

还需要注意的是,Python 有算法创新的历史; Python 中的标准排序算法是TimSort,这是 Tim Peters 发明的一种新算法,以适应 Python 解释器必须处理的实际实际情况。此后,该算法也成为 Java 和 Android 平台的默认算法。因此,我倾向于相信 Python 核心开发人员的决定。

据我所知,没有人嵌入了不同的实现,因为 替换 如果不修补 Python C 代码,默认设置将无法正常工作。当然,您可以轻松创建实现不同搜索算法的专用字符串类型。很可能有一些库将 C 用于使用 Boyer-Moore、Rabin-Karp 或任何其他算法的专门搜索算法,因为对于他们的特定问题域来说,这很可能是更好的选择。

【讨论】:

  • 非常好的答案。很高兴知道 Python 不是从蓝天中诞生的,它的创建者/开发者知道他们在做什么。
  • +1,很好的答案,虽然如果每个人都信任别人,就不会有创新 ;-) ,关于 Rabin-Karp,存储哈希不是问题,因为你是使用单个滚动哈希函数,因此没有理由将其排除。我主要对时间表现感兴趣。今天,内存价格便宜且不那么重要了。
  • @Michael:不确定这是否会使我的回答无效;您没有具体说明效率的含义,您确定可以量化所有情况下一般 python 使用的成本吗?如果是这样,那就把它带到 Python 开发者列表中!请记住,您需要证明的不仅仅是纯粹的速度。
  • @Michael:另外,你继续改变你的问题的前提。这使得 该死的 很难提供答案。请记住,Stack Overflow 上的帖子不仅是为了您自己的利益,也是为了未来的访问者。每次发现新事物时更改问题意味着您应该在论坛或邮件列表上,而不是这样,也许。请留下问题的含义,然后创建新帖子或将其移至 Py 开发列表。
  • @Martijn Pieters:我没有改变问题,我只是证明了python开发人员的当前实现不足以回答你的答案。如果值得在 C 中实现算法并将它们嵌入到 python 中,我仍然感兴趣,你的答案很好,我投了赞成票,如果有人确实实现了我的建议并将其嵌入,我很感兴趣
猜你喜欢
  • 2020-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-27
  • 2015-10-07
  • 2016-12-23
  • 2016-01-04
相关资源
最近更新 更多