【问题标题】:What is the fastest way to search strings in a file?在文件中搜索字符串的最快方法是什么?
【发布时间】:2016-08-28 11:25:59
【问题描述】:

我有一个非常大的文件(100 MB),其中包含字符串,我正在寻找一种高效的方式来查询文件中是否存在给定的字符串。应将整行与输入字符串进行比较。

我的想法是程序加载文件,然后可以查询字符串是否存在。

void loadfile(string filename);
bool stringAvailable(string str);

loadfile() 函数不需要很快,因为它偶尔会被调用。但是 stringAvailable() 需要尽可能的高性能。

目前我已经尝试过:

1.让 linux 命令行工具为我完成这项工作:

system("cat lookup | grep \"^example$\"");

=> 不是很快。

2。拥有 MySQL 数据库而不是文件(我尝试过 MyISAM 和 InnoDB)并像 SELECT count(*) FROM lookup WHERE str = 'xyz'

一样查询它

=> 非常快,但还可以更快。另外,最好有一个不依赖于 DBMS 的程序。

3.拥有一个字符串数组 (string[] ary) 并在 for() 循环中比较所有值。

=> 不是很快。我想它可以使用我目前正在试验的哈希表进行优化。

还有其他可能使该过程更加高效吗?

【问题讨论】:

  • 为什么需要先加载整个文件,而不是读取一行,比较它,然后继续?
  • 因为我会多次查询数据,而且因为磁盘访问比内存访问慢,所以我在内存中工作。 (注意:主要是查找文件,很少更改,所以我一个月只重新加载几次)
  • 好的,这需要逐块读取,并在内存中正确搜索。您可以检查您的操作系统是否提供内存映射文件功能,这可能是最快的。
  • @πάνταῥεῖ - 不,不是。他的 Q 和 cmets 表明他每月有几次将整个文件加载到内存中 - 与顺序文件 IO 无关(也许除了 void loadfile(string filename); - 几乎不是优化问题)。

标签: c++ string performance


【解决方案1】:

将文件中的所有行存储在 std::unordered_set 中。

#include <iostream>
#include <unordered_set>
#include <string>

int main(int argc, char **argv)
{
    std::unordered_set<std::string> lines;
    lines.insert("line 1");
    lines.insert("line 2");

    std::string needle = argv[1];
    if (lines.find(needle) != lines.end())
        std::cout << "found\n";
    else
        std::cout << "NOT found\n";

    return 0;
}

【讨论】:

  • unordered_set 在这里不是更合适吗?
  • 是的 unordered_set 是一个哈希表。
  • 我把它改成了unordered_set。感谢您的建议。
【解决方案2】:

首先将文件加载到内存中。我猜你已经够了。

然后我会尝试在内存中进行线性搜索。如果您开始寻找第一个字符,请停在那里并寻找您正在寻找的连续字符。如果它们的连续字符不匹配,则继续搜索第一个字符,依此类推。

文件是否必须具有模式或在某些条件下进行排序。如果是这种情况,您可能有机会进一步优化。

也尝试使用这样的字符串引用:

void loadfile(const string &filename);
bool stringAvailable(const string &str);

它可能会避免不必要的复制。

【讨论】:

    猜你喜欢
    • 2014-08-27
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多