Delphi:高效快速的Unicode文本搜索

时间:2011-07-19 23:59:21

标签: delphi search text find

Unicode文本/字符串中是否有快速有效的文本搜索?我也需要搜索一个单词的一部分,而不仅仅是一个单词。

SearchBuf?

谢谢!

3 个答案:

答案 0 :(得分:8)

正如已经指出的那样,最快的方法取决于许多事情,最重要的是你是否需要能够反复搜索。第二个问题是,真正拥有“最快”方法而不是合理快速的方法以及您愿意投入优化的时间量对您来说有多重要。

重复搜索

如果您需要重复搜索,我知道的最有效的字符串搜索方法是使用suffix arrays(通常与Burrows-Wheeler transforms结合使用)。这种方法广泛用于生物信息学,其中人们经常需要处理大量数据集上的大量字符串搜索(例如here)。一个非常好的后缀数组(和BWT)库是libdivsufsort C库,但不幸的是我知道没有这个库的Delphi端口。 (我相信这个库能够处理unicode字符串。)

单次搜索

如果您不需要重复搜索,那么强力字符串搜索算法可能会很有效,例如Pos版本的PCMPESTRI和朋友的程序集优化FastCode版本。然而,这些是在Delphi unicode-ified之前编写的,我知道没有类似的优化unicode实现。如果我今天要编写一个并希望针对现代处理器(能够使用SSE4。2指令集)进行优化,我将认真研究{{1}}汇编指令({{3另请参阅例如reference pdf here,但我不知道该代码是否正常工作),它可以处理unicode字符串搜索所需的2字节字符。

答案 1 :(得分:2)

对于某些情况,一种快速有效的搜索算法是(如果搜索的数据没有改变,你只是在同一缓冲区内容上反复搜索)搜索一次并构建某种查找表。一个可能的解决方案是BoyerMoore(请参阅Rudy评论中的链接),但由于那个对于真正的高范围unicode字符(例如范围$ 0000 ... $ FFFF)不起作用,它仍然比重复的Pos或SearchBuf调用更快,但是当我使用真正的高范围Unicode数据集(例如中文文本)进行测试时,它消耗了大量内存。我的观点是没有“扣篮”解决方案。

也许你可以编写一个速度快于Pos-but-not-much-memory-memory-boyerMoore的解决方案:

  1. 为所有角色点构建一个表,并存储每个角色出现的第一个位置。我将使用稀疏排序数组,对于您已完成的每个搜索,存储该初始字符的每个起始位置。这将使您无需通过寻找初始角色匹配的大型unicode字符串进行强力搜索。

  2. 如果表中包含特定字符的NO条目,则必须进行强力搜索(仅一次)以构建该数据集。如果您通过暴力搜索一次并且没有出现代码点U + 1234,那么U + 1234的条目应该是一个空数组[],表示您不必再次搜索,并且可以快速失败搜索初始字符不匹配的位置。

  3. 一旦你找到了一个非空的搜索初始字符列表,比如这个[123,456,789],一个初始的码点匹配,你可以继续在字符串[123 .. .x]然后字符串[456..x],依此类推,直到你的数组中的元素用完为止。任何不匹配都会导致跳转到查找表中的下一个元素。

  4. 同样会有病态的情况,所有这些额外的工作导致代码比Pos快,并且除非你可以确定你需要在完全相同的大字符串中搜索许多不同的子串,然后所有这种“优化”的东西是浪费时间;忘掉它,即使是boyer moore字符串搜索速度较慢,至少你不能多次重复使用查找数据表。

    如果你想要的只是一个Pos()函数,它在Assembly中手动优化,可以在不产生或消耗任何中间表存储的库函数的范围内尽可能快地工作,那么恭喜,Pos ()可能已经达到了你可以获得的速度(我相信它几年前由FastCode人员进行了优化)。

答案 2 :(得分:2)

从实施开始,SearchBufPos/PosEx慢。但它确实有其他选项,如全字搜索和不区分大小写的搜索。

出于您的目的,Pos UnicodeString 版本的IMHO比PosEx慢{Pos使用最慢rep scansw asm而不是两个widechar -hrolled比较PosEx - 至少在Delphi 2010中)。由于我猜你想为你的搜索设置一个起始偏移量(创建一个用于调用Pos的子字符串已经很慢),你想使用PosEx

Bower-More algorithm可能更快。你必须在你的应用程序中尝试使用真实数据来猜测它是否值得。

如果您想搜索英文文本,使用UTF-8进行存储是值得一试的。搜索速度会更快,因为您将使用更少的内存。

但我猜你的应用程序的主要瓶颈在于存储/检索部分(即访问磁盘或取消/压缩),而不是在搜索部分。使用软件探查器猜测值得尝试增强的内容:

  
      
  • 在你快速行动之前做好准备。在你做之前说清楚   它更快。当你加快速度时保持正确。 - Kernighan和   Plauger,编程风格的元素
  •   
  • 过早优化是万恶之源。 - Donald Knuth,   引用C. A. R. Hoare
  •   
  • 表演的关键是优雅,而不是特殊情况的营。   应该抵制调整的可怕诱惑。 - Jon Bentley   和Doug McIlroy
  •   
  • 规则归结为:“1。不要尽早优化.2。不要优化   直到你知道它是必要的。即使这样,也不要优化直到   你知道需要什么,在哪里。“ - Herb Sutter
  •