计算大量文件中单词出现的一般方法

时间:2013-01-04 10:33:42

标签: algorithm

这是一种算法问题。为了说清楚,我对编写代码不感兴趣,而是对如何处理任务感兴趣。

  

我们有一台4 CPU的服务器,没有数据库。磁盘上存储了100,000个HTML文档。每个文档大小为2MB。我们需要一种有效的方法来确定该集合中出现的“CAMERA”(不区分大小写)一词的计数。

我的方法是

  • 解析HTML文档以仅提取单词
  • 然后对单词进行排序,
  • 然后在该集合上使用二进制搜索。

换句话说,我会创建线程让他们使用所有4个CPU将HTML文档解析为单个大字集合文本文件,然后对其进行排序,然后使用二进制搜索。

你怎么看待这个?

5 个答案:

答案 0 :(得分:2)

你试过grep吗?这就是我要做的。

可能需要进行一些实验才能找到正确的方法来传递如此多的数据,并提前确保结果正确,因为这需要一段时间。

我不建议对这么多数据进行排序。

答案 1 :(得分:0)

如果您的文档位于单个本地硬盘驱动器上,则会受到I / O的限制,而不是CPU。

我会使用非常简单的方法简单地将每个文件串行加载到内存中并扫描内存中搜索目标字并增加计数器。

如果你试图使用4个线程来加速它(比如25000个文件到每个线程),它可能会使它变慢,因为I / O不喜欢来自竞争进程/线程的重叠访问模式。

但是,如果文件分布在多个硬盘驱动器上,则应该启动与驱动器一样多的线程,并且每个线程只应从该驱动器读取数据。

答案 2 :(得分:0)

嗯,这不是一个完整的伪代码答案,但我认为没有。要获得最佳性能,您需要了解有关硬件架构的情况。以下是笔记:

  1. 根本不需要对数据进行排序,也不使用二进制搜索。只需读取文件(从磁盘顺序读取每个文件),然后搜索文件中是否显示相机。
  2. 程序中的瓶颈很可能是IO (磁盘读取),因为磁盘访问比CPU计算慢很多。因此,要优化程序 - 应该专注于优化磁盘读取。
  3. 要优化磁盘读取,应该知道它的体系结构。例如,如果您只有一个磁盘(并且没有RAID),那么多线程确实没有意义,假设磁盘可以同时处理单个请求。如果是这种情况 - 使用单个线程。
  4. 但是,如果您有多个磁盘 - 无论您拥有多少个核心,都应该生成#disks threads (假设文件在磁盘中均匀分隔)。由于它是瓶颈,通过让多个线程同时从磁盘请求数据,您可以使它们全部工作,并有效地显着减少时间消耗。

答案 3 :(得分:0)

喜欢什么?

htmlDocuments = getPathsOfHtmlDocuments()
threadsafe counter = new Counter(0)
scheduler = scheduler with max 4 threads
for(htmlDocument: htmlDocuments){
  scheduler.schedule(new SearchForCameraJob("Camera",htmlDocument,counter))
}
wait while scheduler.hasUnfinishedJobs
print Found camera +counter+ times


class SearchForCameraJob(searchString, pathToFile, counter){
    document = readFile(pathToFile);
    while(document.findNext(searchString)){
    counter.increment();    
   }
}

答案 4 :(得分:0)

您可以使用Boyer-Moore算法。很难说什么编程语言适合于这样的应用程序,但你可以在C ++中使用它来直接优化你的本机代码。显然你需要使用多线程。
在HTML文档解析库中,您可以选择Xerces-C ++。