Ну, я собрал тестовую программу, которая запускала каждый из этих методов 100 000 раз, половина для файлов, которые существовали, и половина для файлов, которые не были.
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <fstream>
inline bool exists_test0 (const std::string& name) {
ifstream f(name.c_str());
return f.good();
}
inline bool exists_test1 (const std::string& name) {
if (FILE *file = fopen(name.c_str(), "r")) {
fclose(file);
return true;
} else {
return false;
}
}
inline bool exists_test2 (const std::string& name) {
return ( access( name.c_str(), F_OK ) != -1 );
}
inline bool exists_test3 (const std::string& name) {
struct stat buffer;
return (stat (name.c_str(), &buffer) == 0);
}
Результаты общего времени для выполнения 100 000 вызовов в среднем за 5 запусков,
Method exists_test0 (ifstream): **0.485s**
Method exists_test1 (FILE fopen): **0.302s**
Method exists_test2 (posix access()): **0.202s**
Method exists_test3 (posix stat()): **0.134s**
Эта stat()
функция обеспечивала наилучшую производительность в моей системе (Linux, скомпилированный с g++
), при этом стандартный fopen
вызов - это лучший выбор, если вы по какой-то причине отказываетесь от использования функций POSIX.
boost::filesystem
кажется использоватьstat()
. (Исходя из документации.) Я не думаю, что вы можете делать намного быстрее для вызовов FS. Способ сделать то, что вы делаете быстро, это «избегать просмотра тысяч файлов».