C 在什么都不做時幾乎比 C 慢 4 倍(至少在我的機器上)。當使用 g 編譯以下檔案時,它比使用 gcc 慢 4 倍:
int main() {}
使用time sh -c 'for i in $(seq 0 1000) ; do ./a.out ; done',我得到 C 版本的 0.515 秒,以及 C 版本的 2 秒。這是為什么?
這個程式沒有做任何事情,反匯編的程式在兩個版本中基本相同,那為什么C 版本大約慢4倍?
我的猜測是 C 庫需要更長的時間來加載,但程式集是如此相似,以至于我想不出 C 這么慢的原因。
編輯:好吧,看來我只是部分反匯編了程式(objdump -d而不是objdump -D),導致我看不到正在加載的庫。現在看到反匯編的輸出很明顯,C 版本加載它的庫需要更長的時間。我最初所說的“略有不同”是指在沒有呼叫其他函式的情況下使用mov或call分歧的地址(如果我正確理解objdump' 的輸出的含義)。
所以主要問題解決了,但是對于一個什么都不做的程式來說,2 秒是巨大的。如果有幫助,我使用的是 x86_64 處理器,并且我構建了可執行檔案gcc empty.c和g empty.cpp. 我認為問題確實是我使用硬碟驅動器,因此需要更多時間來加載libstd 。我也使用-static標志構建,現在得到非常相似的結果(0.246s 和 0.241s)。C 二進制檔案也與 C 二進制檔案完全相同(如果這不是diff錯誤的話)。
uj5u.com熱心網友回復:
C 標準庫初始啟動比 C 運行時更重。
C ABI需要為基本語言特性初始化一些結構。互斥鎖,用于資料、例外、執行緒本地存盤、RTTI等的執行緒安全初始化。
這就是為什么使用 C 編譯器創建的空可執行檔案將比空的 C 程式啟動慢的原因。使用匯編語言創建的空程式啟動速度比使用 C 語言創建的具有全功能 C 運行時(CRT、GNU LIBC 等)的類似程式要快得多。
uj5u.com熱心網友回復:
事實上,你根本什么都不比較,因為你的程式什么都不做。您得到的不是程式執行時間,在您的情況下為空,而是流程執行時間,即加載 運行 終止,如果您的程式需要更多資源,則該時間會更長。
一些數字可能會對此有所啟發:
假設我們有emptyc和emptycpp,分別用 gcc-10.3 和 g -10.3 編譯
在我的系統上:
emptyc:- 檔案大小:13232
- elf 動態部分:17 個條目(1 個共享庫)
- truss 系統呼叫報告:48 個系統呼叫,包括 6 個打開和 11 個 mmap
emptycpp- 檔案大小:13312
- elf 動態部分:20 個條目(4 個共享庫)
- truss 系統呼叫報告:88 個系統呼叫,包括 15 個打開和 29 個 mmap
結論:
使用 g 編譯的程式比使用 gcc 編譯的程式需要更多的資源。生成 88 個系統呼叫的行程可能比生成 48 個系統呼叫的行程慢。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/459256.html
