[C++] std::ios::sync_with_stdio scanf printf 與 cin cout 性能問題

如果是學完 C 再來學 C++ 的人應該都有用過這幾種輸入輸出,
但遇到讀取或輸出大量資料的時候,
使用 cincout 就明顯比 scanfprintf 花了更多的時間,
但這不代表就要放棄使用 iostream 去用 stdio

iostream 會比 stdio 慢的多是因為同步的問題,
使用 std::cout 或是 std::cin 的時候,
每次執行輸入輸出都會和 C 的 stdio 進行同步,
大大的降低了執行效率,
要提升效率就要關閉同步,
可以用 std::ios::sync_with_stdio 來關閉同步。

std::ios::sync_with_stdio(false);

但在關閉之後,
就不能將 printf scanfcout cin 混著用了。

像是下面的程式,
輸出可能就不會是理想的樣子。

#include <iostream>

int main()
{
//   std::ios::sync_with_stdio(true);
//   std::ios::sync_with_stdio(false);
  for (int i = 0; i < 5; ++i)
  {
    std::cout << "std::cout << i << std::endl; " << i << std::endl;
    printf("printf(\"%%d\", i); %d\n", i);
  }

//   std::ios::sync_with_stdio(true);
  std::ios::sync_with_stdio(false);

  for (int i = 0; i < 5; ++i)
  {
    std::cout << "std::cout << i << std::endl; " << i << std::endl;
    printf("printf(\"%%d\", i); %d\n", i);
  }
  
  std::ios::sync_with_stdio(true);
//   std::ios::sync_with_stdio(false);

  for (int i = 0; i < 5; ++i)
  {
    std::cout << "std::cout << i << std::endl; " << i << std::endl;
    printf("printf(\"%%d\", i); %d\n", i);
  }

  return 0;
}

output

std::cout << i << std::endl; 0
printf("%d", i); 0
std::cout << i << std::endl; 1
printf("%d", i); 1
std::cout << i << std::endl; 2
printf("%d", i); 2
std::cout << i << std::endl; 3
printf("%d", i); 3
std::cout << i << std::endl; 4
printf("%d", i); 4
std::cout << i << std::endl; 0
std::cout << i << std::endl; 1
std::cout << i << std::endl; 2
std::cout << i << std::endl; 3
std::cout << i << std::endl; 4
std::cout << i << std::endl; 0
std::cout << i << std::endl; 1
std::cout << i << std::endl; 2
std::cout << i << std::endl; 3
std::cout << i << std::endl; 4
printf("%d", i); 0
printf("%d", i); 1
printf("%d", i); 2
printf("%d", i); 3
printf("%d", i); 4
printf("%d", i); 0
printf("%d", i); 1
printf("%d", i); 2
printf("%d", i); 3
printf("%d", i); 4

也有人分別對

  • stdio
  • iostream
  • iostream (關閉同步)

做簡單的性能測試
Link: Using scanf() in C++ programs is faster than using cin?

他的測試結果大致就是:
iostreamscanf 慢了好幾倍
關閉同步的 iostream 甚至比 scanf 還快

這張圖是我自己在寫題目的時候遇到的狀況...

1519471755953

至於該使用 printf 還是 coutscanf 還是 cin
我覺得如果只是學生寫作業解解題,
那就看你喜歡用哪個,
printf scanf 調整格式比較簡單,
iostream 調整格式比較複雜 (iomanip)
我目前也沒找到把 iomanip 整理得比較好的網站,
(如果有的話也可以在下面留言分享)
但如果是在寫專案的話,
考慮到擴展性,
我還是建議使用 iostream

Show Comments