我有一个问题,我正在寻找一些指导以解决最有效的方法。我有2亿个数据字符串,大小从3个字符到70个字符不等。字符串由字母数字和一些特殊字符组成,例如破折号和下划线。我需要能够快速搜索整个字符串或字符串中的任何子字符串(最小子字符串大小为3)。快速定义为少于1秒。
作为我的第一个切入点,我做了以下工作:
搜索/添加服务器作为守护程序运行(在C++中),并且像冠军一样工作。典型的搜索时间少于1/2秒。
问题出在流程的前端。我通常一次添加30,000个 key 。该过程的这一部分需要永远的时间。通过基准测试,装入18万个可变长度键的空索引中的加载时间约为3 1/2小时。
除了非常长的加载时间外,此方案都有效。
在我进行优化(或尝试进行优化)之前,我想知道是否有更好的方法来解决此问题。对于如此大的数据集,前后通配符搜索(例如,DBMS中的字符串,例如'%ppl%')非常慢(例如,在MySQL中为数小时),因此DBMS解决方案似乎是不可能的。我不能使用全文搜索,因为我们不是在处理普通单词,而是可能由真实单词组成的字符串。
最佳答案
根据您的描述,数据加载需要花费所有时间,因为您正在处理I/O,将膨胀的字符串镜像到硬盘。这绝对是一个瓶颈,主要取决于您向磁盘读取和写入数据的方式。
使用带有某些LRU策略的mmap
可以实现执行时间的改善。我非常确定复制数据的想法是为了使搜索更快,但是由于您正在使用-似乎只使用了一台计算机,因此瓶颈将从内存搜索转移到I/O要求。
您可能不感兴趣的另一种解决方案-有趣的是,它也令人讨厌并且令人不安(:-),将数据拆分到多台计算机上。考虑到数据的结构方式,实现本身可能需要一些时间时间,但这将非常简单。您将拥有:
hash_id(bucket) % num_machines
的东西选择存储桶; 正如您所说,另一个好处是,数据是均匀分布的-已经\o/;这通常是分布式实现中最挑剔的部分之一。此外,这将具有很高的可扩展性,因为每当数据大小增加时,您可能会添加另一台计算机。
关于c++ - 快速的字符串搜索,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14467396/