Java 在性能良好的文件中搜索

Java 在性能良好的文件中搜索,java,python-3.x,Java,Python 3.x,我正在尝试在200000个文本文件中实现搜索,这些文件的大小可能从50kb到5MB不等,总计为1.7GB。我计划开发一个搜索引擎(只是一个示例)。 这个过程是: 1) Extract words from each file and store them in a separate file(40,000,000 words) 2) Search each word in each file ( 40,000,000(words) X 200,000(Files) = 8 X 10^12 sea

我正在尝试在200000个文本文件中实现搜索,这些文件的大小可能从50kb到5MB不等,总计为1.7GB。我计划开发一个搜索引擎(只是一个示例)。 这个过程是:

1) Extract words from each file and store them in a separate file(40,000,000 words)
2) Search each word in each file ( 40,000,000(words) X 200,000(Files) = 8 X 10^12 searches)
3) Generate boolean Index(650Mb).
因此,这里涉及的大部分操作都是在文档或文件中搜索。其中第二步需要很多时间。(4+小时)

这是我编写的用JAVA搜索单词的程序

count = 0;
BufferedReader reader = new BufferedReader(new FileReader('fileName.txt'));
while ((text = reader.readLine()) != null) {
if( text.indexOf(searchString) != -1 )
{
    if( text.equals(searchString))
    {
        System.out.print('Word Found in line number '+count);
        break;
    }
}
count++;
}
PYTHON程序:

count = 0
file = open(filePath)
with file as f :
    for line in f:
        count += 1
        if(line.index(searchWord))
            print("Word found in line number"+count)
输出是完美的,但需要很多时间。语言不是我考虑的标准。我在寻找更好的表现。有什么办法可以让我摆脱它吗。因为大部分是搜索过程,有没有什么完美的方法,因为它是搜索大块小块


(My PC Config:8GB RAM,i7第四代)

您可以将文件拆分为多个块,然后使用不同的线程并行处理这些块。(类似于Map Reduce)

示例:将文件拆分为每个100MB的块(假设有17个块)

现在,您可以将这些块传递给各个线程,然后搜索文本

public class SearchText
{

  public void processFile()
  {
    List<Chunks> totalChunks = splitFile(); 
    // you have to implement splitFile() function to split file in chunks

    for(Chunks chunk : totakChunks)
    {
       // Create a new Thread and process the chunks
       new Thread(new ChunkProcessor(chunk)).start();
    }
  }
}

public class ChunkProcessor implements Runnable
{

   private Chunk mychunk ;
   public ChunkProcessor(Chunk chunk)
   {
     myChunk = chunk;
   }


   public void run()
   {
      // search for text in this chunk
   } 
}
公共类搜索文本
{
public void processFile()
{
List totalChunks=splitFile();
//必须实现splitFile()函数才能将文件分割成块
for(Chunks chunk:totakChunks)
{
//创建一个新线程并处理块
新线程(新ChunkProcessor(chunk)).start();
}
}
}
公共类ChunkProcessor实现可运行
{
私有块mychunk;
公共区块处理器(区块)
{
myChunk=chunk;
}
公开募捐
{
//搜索此区块中的文本
} 
}

您可以将文件拆分为多个块,然后使用不同的线程并行处理这些块。(类似于Map Reduce)

示例:将文件拆分为每个100MB的块(假设有17个块)

现在,您可以将这些块传递给各个线程,然后搜索文本

public class SearchText
{

  public void processFile()
  {
    List<Chunks> totalChunks = splitFile(); 
    // you have to implement splitFile() function to split file in chunks

    for(Chunks chunk : totakChunks)
    {
       // Create a new Thread and process the chunks
       new Thread(new ChunkProcessor(chunk)).start();
    }
  }
}

public class ChunkProcessor implements Runnable
{

   private Chunk mychunk ;
   public ChunkProcessor(Chunk chunk)
   {
     myChunk = chunk;
   }


   public void run()
   {
      // search for text in this chunk
   } 
}
公共类搜索文本
{
public void processFile()
{
List totalChunks=splitFile();
//必须实现splitFile()函数才能将文件分割成块
for(Chunks chunk:totakChunks)
{
//创建一个新线程并处理块
新线程(新ChunkProcessor(chunk)).start();
}
}
}
公共类ChunkProcessor实现可运行
{
私有块mychunk;
公共区块处理器(区块)
{
myChunk=chunk;
}
公开募捐
{
//搜索此区块中的文本
} 
}

您可以尝试先使用数据结构构建索引,然后在其上执行搜索。

您可以尝试先使用数据结构构建索引,然后在其上执行搜索。

运行我能买到的运行Windows 7的最便宜笔记本电脑之一

public class SearchTestMain {
    public static void main(String[] args) throws IOException {
        File file = new File("deleteme.txt");
        PrintWriter pw = new PrintWriter(file);
        Random rand = new Random();
        int numbers = 42 * 1000 * 1000;
        long start = System.currentTimeMillis();
        System.out.println("Writing " + file);
        // average line length ~36 bytes.
        for (int i = 0; i < numbers; i++) {
            pw.println(rand.nextLong() & Long.MAX_VALUE); // positive only
            pw.println(rand.nextLong() & Long.MAX_VALUE); // positive only
        }
        pw.close();
        long mid = System.currentTimeMillis();

        System.out.println("Reading " + file);
        BufferedReader br = new BufferedReader(new FileReader(file));
        String searchTerm = "31415926";
        for (String line; ((line = br.readLine())) != null; )
            if (line.contains(searchTerm))
                System.out.println("found " + searchTerm + " in " + line);
        br.close();
        long end = System.currentTimeMillis();
        System.out.printf("Writing took %.1f seconds, reading took %.1f seconds for a %,d MB file%n",
                (mid - start) / 1e3, (end - mid) / 1e3, file.length() / 1000000);
        file.delete();
    }
}

如果仅仅阅读和搜索文本就要花费一分钟以上的时间,我会非常惊讶。如果它需要更长的时间,它正在做一些你没有告诉我们的事情。

运行一台我能买到的最便宜的运行Windows7的笔记本电脑

public class SearchTestMain {
    public static void main(String[] args) throws IOException {
        File file = new File("deleteme.txt");
        PrintWriter pw = new PrintWriter(file);
        Random rand = new Random();
        int numbers = 42 * 1000 * 1000;
        long start = System.currentTimeMillis();
        System.out.println("Writing " + file);
        // average line length ~36 bytes.
        for (int i = 0; i < numbers; i++) {
            pw.println(rand.nextLong() & Long.MAX_VALUE); // positive only
            pw.println(rand.nextLong() & Long.MAX_VALUE); // positive only
        }
        pw.close();
        long mid = System.currentTimeMillis();

        System.out.println("Reading " + file);
        BufferedReader br = new BufferedReader(new FileReader(file));
        String searchTerm = "31415926";
        for (String line; ((line = br.readLine())) != null; )
            if (line.contains(searchTerm))
                System.out.println("found " + searchTerm + " in " + line);
        br.close();
        long end = System.currentTimeMillis();
        System.out.printf("Writing took %.1f seconds, reading took %.1f seconds for a %,d MB file%n",
                (mid - start) / 1e3, (end - mid) / 1e3, file.length() / 1000000);
        file.delete();
    }
}


如果仅仅阅读和搜索文本就要花费一分钟以上的时间,我会非常惊讶。如果需要更长的时间,它会做一些您没有告诉我们的事情。

那么您正试图用Java实现
grep
?为什么您同时使用Java和Python?你想要哪种语言的解决方案?你需要写一个程序吗?或者你可以找一个工具来做这件事吗?它不应该花那么长的时间。您可以以接近100 MB/s的速度读取line(),我预计这不会超过一分钟。您是否运行了一些防病毒程序?因此您正在尝试在Java中实现
grep
?为什么同时使用Java和Python?你想要哪种语言的解决方案?你需要写一个程序吗?或者你可以找一个工具来做这件事吗?它不应该花那么长的时间。您可以以接近100 MB/s的速度读取行(),我预计这不会超过一分钟。您是否运行了一些防病毒程序?(虽然不是在Python中…)@Wooble,可能需要澄清您可以在Python中执行此操作,这对任何事情都没有帮助分割文件通常是按顺序进行的,并且通常需要与读取文件一样长的时间。(虽然不是在Python中…@Wooble,也许澄清一下你可以在Python中进行分割是很好的,它对任何事都没有帮助分割文件通常是按顺序进行的,并且通常需要与读取文件一样长的时间。是的。。这不是程序的全部思想,我还有几个其他任务要执行,在不同的文件中搜索是基本思想。主要目的是实现布尔索引和开发搜索engine@user1919035如果你总共花了10分钟,我怀疑这额外的东西是另外9分钟。i、 e.阅读/搜索只是你问题的10%。@user1919035我建议你使用CPU/内存分析器来查看它大部分时间在做什么。没有测量,我发现我只是在猜测;)不。。我不得不搜索很多这样的文件。。200000个文件(1.7GB),我必须在每个文件中搜索4200万个唯一的单词。我想我需要一次处理一个文件和一个单词。我想搜索可能要晚了。那么,你有什么想法来执行这种类型的搜索吗?@user1919035我猜你有一个硬盘。当你有很多文件时,阅读每一个都需要时间。HDD大约10毫秒,SSD大约0.1毫秒。从磁盘读取200K文件可能需要2000秒或35分钟多一点。幸运的是,您的许多文件将被缓存,因为它倾向于一次读取多个文件。简言之,如果可以的话,不要有那么多的文件,也不要使用硬盘,或者对它们进行碎片整理(把它们放在磁盘上;)是的。。这不是程序的全部思想,我还有几个其他任务要执行,在不同的文件中搜索是基本思想。主要目的是实现布尔索引和开发搜索engine@user1919035如果你