2009-05-22 42 views
23

我一直在C++中編寫很長一段時間。我總是想知道哪個執行速度更快printfcoutcout或printf兩者中哪一個具有更快的執行速度C++?

情況:我正在用C++設計一個應用程序,我有一些限制,比如執行的時間限制。我的應用程序已經在控制檯上加載打印命令。那麼哪一個更可取printfcout

+0

蘋果或橘子:這是美味? – bk1e 2009-05-22 07:31:38

+5

如果對你來說很重要,那就寫一個能兼顧時間和空間的小應用程序。這應該需要15分鐘的時間才能完成。 – 2009-05-22 07:46:11

+3

@尼爾:它不是那麼簡單。 std :: cout和operator <<導致在調用時發出更多的代碼。所有printf邏輯都位於CRT中,但使用運行時邏輯來解釋參數字符串。因此,具有多個呼叫站點和許多不同格式化指令的大型程序可能會看到與小型測試程序不同的效果,只需要一個大的for(很多){printf(「%d」,i); }` – MSalters 2009-05-22 08:29:10

回答

21

每個都有自己的開銷。根據您打印的內容,可能會更快。

下面是我想到兩點 -

的printf()的解析後,它的「格式化」字符串和行爲,這增加了成本。
cout具有更復雜的繼承層次結構並傳遞對象。

實際上,除了最奇怪的情況之外,差異不應該存在。如果你認爲它很重要 - 衡量!

編輯 -
哦,哎呀,我不認爲我這樣做,但爲了記錄在案,我非常具體的測試條件下,我非常具體的機器和它的非常具體的負載,在編譯使用MSVC發佈 -

打印150,000「Hello,World!」s(不使用endl)大約需要 -
對於printf()爲90ms,對於cout爲79ms。

印刷150,000隨機雙打需要約 -
3450ms爲printf(),3420ms爲cout。

(平均超過10次)。

的差異是如此渺茫這可能意味着什麼......

+1

複雜的繼承層次結構和本身傳遞對象都不會導致開銷。 – 2009-05-22 07:06:07

25

你真的需要去關心它具有更快的執行速度?它們都用於簡單地將文本輸出到控制檯/標準輸出,這通常不是要求超高效率的任務。對於這個問題,我不會想象在速度上會有很大差異(儘管一個可能預計printf稍微快一點,因爲它缺乏面向對象的小複雜性)。然而,鑑於我們正在處理I/O操作,即使是微小的差異也可能會被I/O開銷所淹沒。當然,如果你比較寫入文件的等效方法,情況就是這樣。

printf只是將文本輸出到標準輸出文件的標準方法。
「cout」管道僅僅是將文本輸出到標準輸出的標準方式。

說完這一切,comp.lang.cc小組討論了同樣的問題。然而,共識確實是因爲除了表演以外的原因,你應該選擇一個。

6

至少在Windows上,寫入控制檯是一個巨大的瓶頸,所以「噪聲」控制檯模式程序將比無聲控制檯模式程序慢得多。因此,在該平臺上,用於處理控制檯的庫函數的細微差異可能在實踐中沒有顯着差異。

在其他平臺上它可能不同。這也取決於你在做什麼控制檯輸出,相對於其他有用的工作。

最後,它取決於您的平臺的C和C++ I/O庫的實現。

所以這個問題沒有一般的答案。

2

實際上我總是發現printf比cout快。但是再一次,cout在類型安全方面爲您做了更多的工作。還記得printf是一個簡單的函數,而cout是一個基於複雜流層次的對象,所以比較執行時間並不公平。

4

性能是一個無法比較的問題;不能想到它實際計數的任何東西(開發控制檯程序)。但是,您應該考慮幾點:

  • Iostreams使用運算符鏈而不是va_args。這意味着你的程序不能崩潰,因爲你傳遞了錯誤的參數數量。這可能發生在printf上。

  • Iostreams使用運算符重載而不是va_args--這意味着你的程序不能崩潰,因爲你傳遞了一個int並且它期待一個字符串。這可能發生在printf上。

  • Iostreams不支持格式化字符串(這是#1和#2的主要根本原因)。這通常是一件好事,但有時它們很有用。 Boost格式庫爲那些需要定義行爲(拋出異常)而不是未定義行爲(如printf情況下)的用戶提供Iostreams功能。目前這超出了標準。

  • 與他們的printf equivilants不同,Iostreams可以直接處理可變長度的緩衝區,而不是被迫處理硬編碼的cruft。

去找cout。

1

如果你需要找出性能方面的原因,其他東西基本上是錯誤的與您的應用程序 - 可以考慮使用一些其他的日誌記錄工具或UI)

-3

你應該從來沒有需要問這個問題,因爲用戶只能讀取比他們兩個都慢。

如果您需要快速執行,請勿使用。

正如其他人所說的,如果您需要記錄操作,請使用某種記錄。

2

如果您使用的是C++,則應該使用cout,因爲printf屬於C系列函數。對於您可能受益的cout有許多改進。至於速度,這不是問題,因爲控制檯I/O無論如何都會變慢。

2

爲了解決這樣的:

#include <iostream> 
#include <cstdio> 
#include <ctime> 
using namespace std; 

int main(int argc, char * argcv[]) { 
    const char * const s1 = "some text"; 
    const char * const s2 = "some more text"; 
    int x = 1, y = 2, z = 3; 
    const int BIG = 2000; 
    time_t now = time(0); 
    for (int i = 0; i < BIG; i++) { 
     if (argc == 1) { 
      cout << i << s1 << s2 << x << y << z << "\n"; 
     } 
     else { 
      printf("%d%s%s%d%d%d\n", i, s1, s2, x, y, z); 
     } 
    } 
    cout << (argc == 1 ? "cout " : "printf ") << time(0) - now << endl; 
} 

產生用於cout和printf的相同定時。

-2

軼事證據:
我曾經設計過一個使用ostream操作符的日誌類 - 實現速度非常慢(對於大量數據)。

我沒有太多分析,所以它可能是由於沒有正確使用ostreams,或者僅僅是由於大量的數據記錄到磁盤造成的。 (由於性能問題,班級已被報廢,實際上printf/fmtmsg風格是首選。)

我同意其他答覆,在大多數情況下,這並不重要。如果輸出確實是一個問題,您應該考慮避免/延遲它的方法,因爲實際的顯示更新通常比正確實施的字符串構建花費更多。無論如何,在數毫秒內滾動的數千行信息不是很豐富。

0

在引擎蓋下,它們都將使用相同的代碼,所以速度差異將無關緊要。

如果你只在Windows上運行,非標準的cprintf()可能會更快,因爲它繞過了很多流的​​東西。

然而,這是一個奇怪的要求。沒人能快速閱讀。爲什麼不將輸出寫入文件,那麼用戶可以在閒暇時瀏覽文件?

1

我最近在使用CopyFileEx複製文件的窗口上工作的C++控制檯應用程序,並將每個副本的「到」和「從」路徑回顯到控制檯,然後在操作結束時顯示平均吞吐量。

當我使用printf運行控制檯應用程序來回顯字符串時,我得到4mb /秒,當用std :: cout替換printf時,吞吐量降至800kb/sec。

我想知道爲什麼std :: cout調用是如此昂貴,甚至竟然在每個副本上回顯出相同的字符串以獲得對調用的更好比較。我做了多次運算來平衡比較,但4倍的差異仍然存在。

然後我發現計算器this答案..

的printf和性病::法院接通緩衝標準輸出的伎倆,現在我吞吐量數字幾乎相同。

我還沒有深入瞭解printf和cout在控制檯輸出緩衝方面的差異,但是在開始寫入控制檯之前設置輸出緩衝區解決了我的問題。

0

你爲什麼不去做實驗?平均來說,打印字符串helloperson; \ n使用printf平均需要2個時鐘滴答,而使用endl的cout需要大量時間 - 1248996720685時鐘滴答。將「\ n」作爲換行符使用cout只需要41981個時鐘刻度。我的代碼的短網址低於:

cpp.sh/94qoj

鏈接可能已經過期。

要回答你的問題,printf會更快。

#include <iostream> 
#include <string> 
#include <ctime> 
#include <stdio.h> 
using namespace std; 
int main() 
{ 
    clock_t one; 
    clock_t two; 
    clock_t averagePrintf; 
    clock_t averageCout; 
    clock_t averagedumbHybrid; 
    for (int j = 0; j < 100; j++) { 
    one = clock(); 
    for (int d = 0; d < 20; d++) { 
     printf("helloperson;"); 
     printf("\n"); 
    } 
    two = clock(); 
    averagePrintf += two-one; 

    one = clock(); 
    for (int d = 0; d < 20; d++) { 
     cout << "helloperson;"; 
     cout << endl; 
    } 
    two = clock(); 
    averageCout += two-one; 

    one = clock(); 
    for (int d = 0; d < 20; d++) { 
     cout << "helloperson;"; 
     cout << "\n"; 
    } 
    two = clock(); 
    averagedumbHybrid += two-one; 
    } 
    averagePrintf /= 100; 
    averageCout /= 100; 
    averagedumbHybrid /= 100; 
    cout << "printf took " << averagePrintf << endl; 
    cout << "cout took " << averageCout << endl; 
    cout << "hybrid took " << averagedumbHybrid << endl; 
} 

是的,我確實使用了dumb這個詞。我第一次爲自己做了這件事,認爲結果很瘋狂,所以我搜索了它,最終發佈了我的代碼。

希望它能幫助, Ndrewffght

相關問題