1

搜索但似乎没有找到我需要的东西。

我正在寻找运行以下命令的快速 C++ 等效项:

diff file1.log file2.log | wc -l

目前,我正在使用文件管道来从命令行运行 diff,但是我需要在一个大型的、多嵌套的循环中执行此操作,并且花费的时间比我预期的要长得多。被区分的文件每个大约 150-200mb,每个 diff 大约需要 1-2 分钟。

是否有可以通过 C++ 推出的更快解决方案?

这是我目前的调用方法:

static std::string run_cmd(std::string in)
{
  // run command
  FILE* pipe = popen(in.c_str(), "r");
  if (!pipe)  return "err";

  char buff[128];
  std::string res = "";
  while (!feof(pipe))
  {
    if (fgets(buff, 128, pipe) != NULL)
      res += buff;
  }
  pclose(pipe);
  return res;
}

// diff 2 given files and return line number differences
std::string fileDiff(std::string file1, std::string file2)
{
  std::string f1 = base + file1;
  std::string f2 = base + file2;
  std::string cmd = "diff " + f1 + " " + f2 + " | wc -l";

  std::string res = run_cmd(cmd);
  if (res == "err") 
    return "E: Diff on [" + f1 + "] and [" + f2 + "]";

  return res;
}

编辑:

我本质上在做的是记录代码覆盖率。我已将日志记录语句插入到我正在使用的代码库的每个角落和缝隙中,并将每次运行写入其自己的日志文件。我试图通过不将它们包含在构造函数、循环等中来最小化写入损失,并缓冲了实际的写入过程。

我运行的程序通常需要大约 10 分钟。随着我添加的日志记录和差异调用,它的规模扩大到大约 1 天。

在这种情况下,我只关心线条差异的数量,因为它在遗传算法中提供了适应度函数。在这一点上,迭代之间执行路径的分布很重要。

4

2 回答 2

2

启动外部进程很快。在每个文件 1-2 分钟时,进程生成开销只是很小的一部分。您必须受限于 1) diff 命令的性能或 2) 管道输出数据的读取和存储效率低下。尝试在 shell 中运行 diff 命令并输出到文件中。是不是快很多?如果没有,那么 1)。如果是这样,那么 2)。

我对 Unix 管道了解不多,但 128 字节的缓冲区听起来很小。diff 命令很旧并且被广泛使用,因此您不太可能编写更快的版本。

于 2012-09-07T15:06:59.267 回答
1

我可以看到两种可能性。

一是简化问题。diff做了很多工作来找到将一个文件转换为另一个文件的最小编辑集。如果您只想知道两个文件之间有多少行不同,而不关心一个如何转换为另一个,您可以通过在每个文件中简单地构建一组行来获得一些速度,并且获取set_symmetric_difference它们之间的大小。

第二个是,如果您正在寻找(例如)最相似/最不相似的文件,那么现在您可能正在重新计算每个文件和每个其他文件之间的差异。换句话说,您有一个二次问题,并且给定 N 个文件,您要重新读取每个文件 N 次。

根据您要完成的任务和文件的数量,您很有可能只能读取每个文件一次。例如,如果您对每一行进行哈希处理,并且只存储一组哈希值,您可能可以一次将所有文件的数据放入内存中,因此操作的二次部分可以完全在内存中进行,而不是多次重新读取每个文件次。

于 2012-09-07T15:27:15.577 回答