Низкая производительность C ++ std :: filesystem :: directory_iterator для символических ссылок - PullRequest
1 голос
/ 28 марта 2020

Я понимаю, что std :: filesystem не является демоном скорости. Но по сравнению с opendir/readdir я вижу, что время выполнения для std::filesystem::directory_iterator в 8-10 раз больше (Ubuntu 18.04, clang 9.0.0). Теперь мне интересно, если я делаю что-то не так или, по крайней мере, надеюсь на некоторое понимание, почему это (так сильно) медленнее.

Более подробно: я сравниваю эти две, почти идентичные функции:

    int32_t GetNumberOfFilesStdFilesys(const std::filesystem::path& testDir) {
    // Find all files in that testDir
    int32_t numFiles = 0;
    for (auto& dirent : std::filesystem::directory_iterator(testDir)) {
        if (dirent.is_regular_file() || dirent.is_symlink()) {
            // const std::string filename(dirent.path().filename());
            numFiles++;
        }
    }
    return numFiles;
}

int32_t GetNumberOfFilesStdC(const std::filesystem::path& testDir) {
    // Find all files in that testDir
    int32_t numFiles = 0;
    DIR* dir = opendir(testDir.string().c_str());
    for (struct dirent* entry = readdir(dir); entry != NULL; entry = readdir(dir
)) {
        if (entry->d_type == DT_REG || entry->d_type == DT_LNK) {
            // const std::string filename(entry->d_name);
            numFiles++;
        }
    }
    closedir(dir);
    return numFiles;
}

Они ходят по каталогу и подсчитывают обычные и символические c ссылки. Затем я запускаю это в al oop 30000 раз для каталога с 100 символическими ссылками и 300 раз для каталога с 10000 символическими ссылками. Вот результат:

Symlink (Number Files: 100, Iterations: 30000)
    Std C lib       CPU time: 443.91 msec       Wall clock: 446.97 msec
    std::filesystem     CPU time: 3908.20 msec      Wall clock: 3910.18 msec
Symlink (Number Files: 10000, Iterations: 300)
    Std C lib       CPU time: 455.26 msec       Wall clock: 455.92 msec
    std::filesystem     CPU time: 5090.57 msec      Wall clock: 5090.61 msec

ЦП измеряется с помощью std::clock, а Walltime с std::chrono::high_resolution_clock. Я предполагаю, что directory_iterator обрабатывает больше данных, возможно, следуя символической ссылке (?) - есть ли флаги, чтобы предотвратить это? Или это просто цена абстракции платформы?

Спасибо за понимание!

...