全文匹配的各种搜索算法和性能

Posted

技术标签:

【中文标题】全文匹配的各种搜索算法和性能【英文标题】:Various search algorithms and performance for full text matching 【发布时间】:2019-12-24 03:12:07 【问题描述】:

假设我有以下字符串:

/Volumes/01/LG_SICARIO_ES419SUB_16X9_240_2398_DIGITAL_FINAL.itt

在给定输入条件['sicario', '419']的情况下,我将如何确定在此字符串中搜索匹配项的最快方法

例如,最基本的版本是:

1) 字符串包含:

s = '/Volumes/01/LG_SICARIO_ES419SUB_16X9_240_2398_DIGITAL_FINAL.itt'
terms = ['sicario', '419']
has_match = all([term.lower() in s.lower() for term in terms])

2) 正则表达式

has_match = all([re.compile(term, re.I).search(s) for term in terms])

其他可能的选择是:

拉宾-卡普 博耶-摩尔 和其他string-searching algorithms

各种算法的时间复杂度是多少?


这是我得到的计时regex vs str() in

 import timeit

 # Case insensitive
setup =  's="/Volumes/01/LG_SICARIO_ES419SUB_16X9_240_2398_DIGITAL_FINAL.itt"; terms = ["sicario", "419"]'
print min(timeit.Timer('all([term in s.lower() for term in terms])', setup=setup).repeat(7, 1000))
0.00134181976318

# Case sensitive
setup =  's="/Volumes/01/LG_SICARIO_ES419SUB_16X9_240_2398_DIGITAL_FINAL.itt"; terms = ["sicario", "419"]'
print min(timeit.Timer('all([term in s for term in terms])', setup=setup).repeat(7, 1000))
0.000231027603149


# Regex case insensitive
setup =  'import re; s="/Volumes/01/LG_SICARIO_ES419SUB_16X9_240_2398_DIGITAL_FINAL.itt"; compiled_terms = [re.compile("sicario", re.I), re.compile("419", re.I)]'
print min(timeit.Timer('all([compiled_term.search(s) for compiled_term in compiled_terms])', setup=setup).repeat(7, 1000))
0.00111889839172


# Regex case sensitive
setup =  'import re; s="/Volumes/01/LG_SICARIO_ES419SUB_16X9_240_2398_DIGITAL_FINAL.itt"; compiled_terms = [re.compile("sicario"), re.compile("419")]'
print min(timeit.Timer('all([compiled_term.search(s) for compiled_term in compiled_terms])', setup=setup).repeat(7, 1000))
0.000588893890381

虽然区分大小写的字符串搜索的性能比正则表达式高 2 倍左右(至少在这个输入数据上),但它非常接近。

【问题讨论】:

【参考方案1】:

我认为您的基本版本是最快的 (a combination of Boyer-Moore and Horspoo)(在良好情况下的次线性搜索行为 (O(n/m)),我将对您的基本版本进行一些小改动:

def test():
    lower_s = s .lower()
    return all([term in lower_s for term in terms])

【讨论】:

@ruso -- 你能解释一下为什么它会是最快的吗?基本上我正在尝试更多地了解幕后的算法等,以及为什么一种方法会比另一种更好。 你也可以看看搜索算法/单模式算法的基本分类en.wikipedia.org/wiki/String-searching_algorithm 我认为是最快的,因为它是用c实现的

以上是关于全文匹配的各种搜索算法和性能的主要内容,如果未能解决你的问题,请参考以下文章

什么是Elasticsearch

ElasticSearch实战-TF/IDF/BM25分值计算(文本搜索排序分值计算,全文检索算法,文本相似度算法)

ElasticSearch实战-TF/IDF/BM25分值计算(文本搜索排序分值计算,全文检索算法,文本相似度算法)

MongoDB全文搜索和查找运算符

django全文检索

搜索引擎之全文搜索算法功能实现(基于Lucene)