Bem, juntei um programa de teste que executou cada um desses métodos 100.000 vezes, metade em arquivos que existiam e metade em arquivos que não existiam.
#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);
}
Resultados do tempo total para executar as 100.000 chamadas em média em 5 execuções,
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**
A stat()
função forneceu o melhor desempenho no meu sistema (Linux, compilado com g++
), com uma fopen
chamada padrão sendo sua melhor aposta se, por algum motivo, se recusar a usar as funções POSIX.
boost::filesystem
parece usarstat()
. (Assumindo a partir da documentação.) Não acho que você possa fazer muito mais rápido para chamadas de FS. A maneira de acelerar o que você está fazendo é "evitar a visualização de milhares de arquivos".