首頁  >  文章  >  後端開發  >  C IOStreams 總是比 printf/scanf 慢嗎?

C IOStreams 總是比 printf/scanf 慢嗎?

Barbara Streisand
Barbara Streisand原創
2024-11-06 15:55:02148瀏覽

Is C   IOStreams Always Slower Than printf/scanf?

增強IOStream 效能的策略

大多數C 程式設計師在用C 進行編碼時更喜歡printf/scanf 函數,因為它們具有優越的接口。然而,IOStreams 經常面臨效能問題。

緩衝最佳化

增加緩衝區大小可以透過減少 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn