递归列出所有目录中的C++与Python与Ruby的性能

C++ vs Python vs Ruby Performance in Listing All Directories Recursively

本文关键字:C++ Python 性能 Ruby 递归      更新时间:2023-10-16

我刚刚写了一个C++代码,以递归方式列出文件夹中的所有目录。我使用Boost文件系统,并静态构建了以下代码:

#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&红宝石我知道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模式,并且Optimization设置为Maximum Optimization(Favor Speed((/O2(。

为什么C++代码在面对大量递归文件夹时速度较慢?

通过使用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版本则没有。

我只能得出结论,C++版本的实现效率不如Ruby版本(或者它可能有不同的用途(。速度差异不是语言问题,而是实现问题。

注意:带有-O优化的C++版本的运行时间为0.347s,而Ruby版本的运行速度为0.304s。至少在Linux上,lstat似乎不会产生太多开销。也许Windows上的情况有所不同。