あるディレクトリ内のファイル(+ディレクトリ)数を取得する必要があったのですが,Boost.Filesystem と FindFirstFile とでどの程度の速度差になるのかなと思い調べてみました.まず,Boost.Filesystem 版のファイル数カウント関数.
#include <string> #include <boost/filesystem.hpp> std::size_t file_count_boost(const boost::filesystem::path& root) { namespace fs = boost::filesystem; if (!fs::exists(root) || !fs::is_directory(root)) return 0; std::size_t result = 0; fs::directory_iterator last; for (fs::directory_iterator pos(root); pos != last; ++pos) { ++result; if (fs::is_directory(*pos)) result += file_count_boost(pos->path()); } return result; }
次に FindFirstFile を使ったファイル数カウント関数.
#include <string> #include <windows.h> #include <tchar.h> std::size_t file_count_native(const std::basic_string<TCHAR>& src) { std::basic_string<TCHAR> root = src + _T("\\*.*"); WIN32_FIND_DATA wfd = {}; HANDLE handle = FindFirstFile(root.c_str(), &wfd); if (handle == INVALID_HANDLE_VALUE) return 0; std::size_t result = 0; do { std::basic_string<TCHAR> path(wfd.cFileName); if (path != _T(".") && path != _T("..")) { ++result; if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) result += file_count_native(src + _T('\\') + path); } } while (FindNextFile(handle, &wfd)); FindClose(handle); return result; }
実行結果
テストは,実行環境にある boost_1_46_1 ディレクトリを指定して調べてみました.実行環境の boost_1_46_1 ディレクトリには,37,834 ファイルと 3,233 ディレクトリが存在するようです.
Boost.Filesystem を使用した場合 $ time ./file-scanning-test.exe 41067 real 0m3.135s user 0m0.000s sys 0m0.015s FindFirstFile を使用した場合 $ time ./file-scanning-test.exe 41067 real 0m0.363s user 0m0.031s sys 0m0.000s
実行すると 1桁くらい実行速度が変わっていました.さすがに 1桁も変わるとは思っていなかったので驚きました.やはり変なものを指定される(馬鹿でかいファイルとか)可能性のある部分は,ネイティブ(ここだと Win32 API)で書いておかないとまずい場合があると言う事でしょうか.