我刚刚编写了一个C ++代码来递归列出文件夹中的所有目录。我正在使用Boost Filesystem,并且已经静态构建了以下代码:
#include <iostream>
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
using namespace std;
int main(int argc, char* argv[]) {
const path current_file_path(current_path());
try {
std::vector<path> directories_vector;
for (auto&& x : recursive_directory_iterator(current_file_path))
if (is_directory(x.path()))
directories_vector.push_back(x.path());
/* GETTING UP TO HERE TAKES MORE TIME THAN PYTHON OR RUBY*/
for (auto&& x : directories_vector) {
cout << x << '\n';
}
}
catch (const filesystem_error& ex) {
cout << ex.what() << '\n';
}
cin.get();
return 0;
}
我想看看这段代码在Python和Ruby上的运行速度。我知道与I / O相关的东西并不能很好地评估代码性能,但是当我运行C ++可执行文件时,15个递归文件夹大约需要3秒钟,而以下Python和Ruby代码几乎可以立即运行:
Ruby:
Dir.glob("**/*/")
Python:
[x[0] for x in os.walk(directory)]
所有代码都在SSD上运行。我在Windows上使用Visual Studio 2017,Python 3.5.2和Ruby 2.4。 C ++代码使用Release / x64模式,并且“优化”设置为“最大优化(最快速度)(/ O2)”。
面对许多递归文件夹时,为什么C ++代码会变慢?
答案 0 :(得分:2)
通过同时使用strace
运行C ++版本和Ruby版本,我们可以得到一些线索,以了解C ++版本较慢的原因。
使用Linux源代码进行测试(65000个文件):
strace -o '|wc' cpp_recursion
86417 518501 9463879
strace -o '|wc' ruby -e 'Dir.glob("**/*")'
30563 180115 1827588
我们看到C ++版本的操作量比Ruby高出近3倍。
更仔细地查看strace输出,您会发现这两个程序都使用getdents
来检索目录条目,但是C ++版本在每个文件上都运行lstat
,而Ruby版本则没有。 / p>
我只能得出结论,C ++版本没有像Ruby版本那样有效地实现(或者可能有不同的用途)。速度差异不是语言问题,而是实现问题。
具有-O
优化的C ++版本在0.347s中运行,而Ruby版本在0.304s中运行。至少在Linux lstat
上似乎不会产生太多开销。在Windows上,情况可能有所不同。