ホームページ >バックエンド開発 >C++ >C IOStreams は常に printf/scanf より遅いですか?

C IOStreams は常に printf/scanf より遅いですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-06 15:55:02242ブラウズ

Is C   IOStreams Always Slower Than printf/scanf?

IOStream のパフォーマンスを向上させる戦略

ほとんどの C プログラマは、優れたインターフェイスを理由に、 C でコーディングする場合は printf/scanf 関数を好みます。ただし、IOStream はパフォーマンスの問題に直面することがよくあります。

バッファリングの最適化

バッファ サイズを増やすと、HDD ヒットとシステム コールが減少し、パフォーマンスが向上します。これは、基になる streambuf にアクセスし、そのバッファを変更することで実現できます。

char Buffer[N];

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

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

ロケール処理

ロケールでは、文字変換や文字変換などの複雑な操作によりパフォーマンスのオーバーヘッドが発生する可能性があります。フィルタリング。均一性と最小限の変換を目的として設計されたデフォルトの C ロケールの使用を検討してください。

同期

stdio との同期によってパフォーマンスが向上することはないようです。ただし、std::ios_base::sync_with_stdio を使用してグローバル設定にアクセスすることは可能です。

測定と結果

パフォーマンスの結果は、実装とプラットフォームによって大きく異なります。一部のユーザーは C IOStream の速度が速いと報告していますが、他のユーザーはパフォーマンスが遅いと報告しています。

ベンチマーク コード

独自のベンチマークの実行に興味がある方のために、サンプル コードを次に示します。

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;
}

以上がC IOStreams は常に printf/scanf より遅いですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。