Ich brauche eine schnelle Funktion, die prüfen kann, ob eine Datei vorhanden ist oder nicht, und PherricOxides Antwort ist fast das, was ich brauche, außer dass sie nicht die Leistung von boost::filesystem::exists und open-Funktionen vergleicht. Aus den Benchmark-Ergebnissen können wir leicht erkennen, dass :
-
Die Verwendung der stat-Funktion ist der schnellste Weg, um zu prüfen, ob eine Datei vorhanden ist. Beachten Sie, dass meine Ergebnisse mit denen der Antwort von PherricOxide übereinstimmen.
-
Die Leistung der Funktion boost::filesystem::exists kommt der der Funktion stat sehr nahe, und sie ist auch portabel. Ich würde diese Lösung empfehlen, wenn die boost-Bibliotheken über Ihren Code zugänglich sind.
Die Benchmark-Ergebnisse wurden mit Linux-Kernel 4.17.0 und gcc-7.3 erzielt:
2018-05-05 00:35:35
Running ./filesystem
Run on (8 X 2661 MHz CPU s)
CPU Caches:
L1 Data 32K (x4)
L1 Instruction 32K (x4)
L2 Unified 256K (x4)
L3 Unified 8192K (x1)
--------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------
use_stat 815 ns 813 ns 861291
use_open 2007 ns 1919 ns 346273
use_access 1186 ns 1006 ns 683024
use_boost 831 ns 830 ns 831233
Nachstehend finden Sie meinen Benchmark-Code:
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include "boost/filesystem.hpp"
#include <benchmark/benchmark.h>
const std::string fname("filesystem.cpp");
struct stat buf;
// Use stat function
void use_stat(benchmark::State &state) {
for (auto _ : state) {
benchmark::DoNotOptimize(stat(fname.data(), &buf));
}
}
BENCHMARK(use_stat);
// Use open function
void use_open(benchmark::State &state) {
for (auto _ : state) {
int fd = open(fname.data(), O_RDONLY);
if (fd > -1) close(fd);
}
}
BENCHMARK(use_open);
// Use access function
void use_access(benchmark::State &state) {
for (auto _ : state) {
benchmark::DoNotOptimize(access(fname.data(), R_OK));
}
}
BENCHMARK(use_access);
// Use boost
void use_boost(benchmark::State &state) {
for (auto _ : state) {
boost::filesystem::path p(fname);
benchmark::DoNotOptimize(boost::filesystem::exists(p));
}
}
BENCHMARK(use_boost);
BENCHMARK_MAIN();