在Java中从缓冲区进行高效模式搜索?

在Java中从缓冲区进行高效模式搜索?,java,algorithm,search,buffer,Java,Algorithm,Search,Buffer,在使用缓冲区搜索字节模式时,我一直在试图找到一种高效的工作方式,无需从文件中读取两次。我选择实现Runnable,这样我就可以将任务划分为并发线程。我的代码如下所示: // constructor: initializes local variables. public BytePatternSearcher(RandomAccessFile raFile, byte[] pattern, int bufferSize, long startPos, long endPos); public

在使用缓冲区搜索字节模式时,我一直在试图找到一种高效的工作方式,无需从文件中读取两次。我选择实现Runnable,这样我就可以将任务划分为并发线程。我的代码如下所示:

// constructor: initializes local variables.
public BytePatternSearcher(RandomAccessFile raFile, byte[] pattern, int bufferSize, long startPos, long endPos);

public void run()
{
    while(amountToRead - raFile.read(buffer) > 0)
    {
        // search code
    }
{
现在,我遇到了一个障碍:我的算法适用于简单的情况,但不适用于复杂的情况。我假设没有一个模式从已经被搜索的一个模式开始,模式长度比缓冲区短,等等,一次只扫描一次,只是在文件中迭代。当然,这不是一个非常稳健的解决方案。假设我有一个'xxxxx'(长度5)的模式,我的文件是'xxxxxx-yxxxxxx',我的缓冲区大小是2(x和y代表某些字节值)。字符串出现4次,每次检查需要缓冲区长度的两倍以上


如何在不检查同一字节的情况下解决所有问题?

维基百科有一个条目,其中还包含一些示例实现。

查找Knuth-Morris-Pratt算法。我不认为“设计模式”标记正在应用在这一点上添加多个线程几乎肯定是过早的优化,并且当您试图一次将整个文件加载到内存中时,很可能会出现内存不足错误。相反,使用顺序算法(B-M是一个不错的选择),跟踪匹配,或者(1)在找到它们时处理它们,或者(2)不要担心读取文件两次(因为它的许多块可能在操作系统缓冲区中)。@kdgregory这对我来说是一个理论实践。我想使用内存和线程约束来寻找最大性能。但基本上,我们的想法是将它分成X个线程,X是可用的内核数量,总内存/X用于内存使用,每个线程将得到1/X的文件来处理-我只会为每个线程发送指针,指示搜索的开始和结束位置。在这种情况下,这里有两条实用的建议:第一:单个内核执行字节线性扫描的速度比任何磁盘提供这些字节的速度都快;通过将高CPU工作传递给后台线程,而平均线程找到该工作,可以获得性能优势。第二:慢而正确比快而错误要好。如果您不处理跨越边界的数据,那么您的代码几乎肯定是错误的。