Heim  >  Artikel  >  Backend-Entwicklung  >  Ist C IOStreams immer langsamer als printf/scanf?

Ist C IOStreams immer langsamer als printf/scanf?

Barbara Streisand
Barbara StreisandOriginal
2024-11-06 15:55:02148Durchsuche

Is C   IOStreams Always Slower Than printf/scanf?

Strategien zur Verbesserung der IOStream-Leistung

Die meisten C-Programmierer bevorzugen die printf/scanf-Funktionen beim Codieren in C und verweisen auf deren überlegene Schnittstelle. Bei IOStreams treten jedoch häufig Leistungsprobleme auf.

Pufferoptimierung

Eine Erhöhung der Puffergröße verbessert die Leistung, indem Festplattentreffer und Systemaufrufe reduziert werden. Dies kann erreicht werden, indem auf den zugrunde liegenden Streambuf zugegriffen und dessen Puffer geändert wird:

char Buffer[N];

std::ifstream file("file.txt");

file.rdbuf()->pubsetbuf(Buffer, N);

Gebietsschema-Handhabung

Gebietsschemas können aufgrund komplexer Vorgänge wie Zeichenkonvertierung und mehr zu Leistungseinbußen führen Filterung. Erwägen Sie die Verwendung des Standardgebietsschemas C, das auf Einheitlichkeit und minimale Konvertierungen ausgelegt ist.

Synchronisierung

Die Synchronisierung mit stdio scheint die Leistung nicht zu verbessern. Es ist jedoch möglich, mit std::ios_base::sync_with_stdio auf eine globale Einstellung zuzugreifen.

Messungen und Ergebnisse

Leistungsergebnisse variieren erheblich je nach Implementierung und Plattform. Einige Benutzer haben schnellere C IOStreams gemeldet, während andere eine langsamere Leistung festgestellt haben.

Benchmarking-Code

Für diejenigen, die ihre eigenen Benchmarks ausführen möchten, finden Sie hier einen Beispielcode:

template <typename Func>
double benchmark(Func f, size_t iterations)
{
  f();

  timeval a, b;
  gettimeofday(&a, 0);
  for (; iterations--;)
  {
    f();
  }
  gettimeofday(&b, 0);
  return (b.tv_sec * (unsigned int)1e6 + b.tv_usec) -
         (a.tv_sec * (unsigned int)1e6 + a.tv_usec);
}

struct CRead
{
  CRead(char const* filename): _filename(filename) {}

  void operator()() {
    FILE* file = fopen(_filename, "r");

    int count = 0;
    while (fscanf(file,"%s", _buffer) == 1) { ++count; }

    fclose(file);
  }

  char const* _filename;
  char _buffer[1024];
};

struct CppRead
{
  CppRead(char const* filename): _filename(filename), _buffer() {}

  enum { BufferSize = 16184 };

  void operator()() {
    std::ifstream file(_filename, std::ifstream::in);

    file.rdbuf()->pubsetbuf(_buffer, BufferSize);

    int count = 0;
    std::string s;
    while (file >> s) { ++count; }
  }

  char const* _filename;
  char _buffer[BufferSize];
};

int main(int argc, char* argv[])
{
  size_t iterations = 1;
  if (argc > 1) { iterations = atoi(argv[1]); }

  char const* oldLocale = setlocale(LC_ALL,"C");
  if (strcmp(oldLocale, "C") != 0) {
    std::cout << "Replaced old locale '" << oldLocale << "' by 'C'\n";
  }

  char const* filename = "largefile.txt";

  CRead cread(filename);
  CppRead cppread(filename);

  bool oldSyncSetting = std::ios_base::sync_with_stdio(false);

  double ctime = benchmark(cread, iterations);
  double cpptime = benchmark(cppread, iterations);

  std::ios_base::sync_with_stdio(oldSyncSetting);

  std::cout << "C  : " << ctime << "\n"
               "C++: " << cpptime << "\n";

  return 0;
}

Das obige ist der detaillierte Inhalt vonIst C IOStreams immer langsamer als printf/scanf?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn