C ++ vs Python vs Ruby性能以递归方式列出所有目录

时间:2018-11-02 15:16:53

标签: python c++ ruby performance

我刚刚编写了一个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 ++代码会变慢?

1 个答案:

答案 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上,情况可能有所不同。