RenameFile
是內聯的,因爲它是對另一個函數的簡單調用。
這裏是什麼樣子:
function RenameFile(const OldName, NewName: string): Boolean;
{$IFDEF MSWINDOWS}
begin
Result := MoveFile(PChar(OldName), PChar(NewName));
end;
通過內聯這個函數調用SysUtils.RenameFile
得到通過調用替換爲WinApi.Windows.MoveFile
。
這具有以下優點:
- 你保存在呼叫,而不是兩個電話,你只需要一個電話。
- 您的調用代碼大小完全相同。
- CPU保留分支預測(返回堆棧緩衝區)的返回地址列表;通過消除冗餘調用,可以節省此緩衝區中的空間,從而防止調用堆棧變得太深時發生預測失誤。
- 生成的代碼較小,因爲
RenameFile
本身被取消。
所以內聯是非常值得的麻煩,尤其是在遞歸代碼在調用堆棧可以得到深層的CPU將開始mispredicting的回報,因爲返回堆棧緩衝區溢出(一些CPU的只有8項,頂部線CPU有24個條目)。
通常,每個調用另一個例程的例程都應該內聯。
一個正確的預測回報需要花費一個週期,一個錯誤預測會清空管道,花費25個週期或更多;由於返回地址需要從存儲器而不是緩衝區中獲取,所以會增加進一步的延遲。
你是正確的,這些優點都不會影響磁盤IO代碼,但這並沒有減少這樣的簡單重定向函數應該總是內聯的事實。
出於同樣的原因,他們宣佈它的參數「const」......性能增益可能不是那麼有意義,但它或多或少是免費的。 (如果你不知道,當它傳遞給一個函數時,聲明一個字符串參數'const'去掉引用計數的Inc/dec)。 –
@ KenBourassa-CONST實際上做的不僅僅是這些,而且在某些條件下(經常遇到)速度增益很大。 – Ampere
以及它在字符串的上下文中還做了什麼?對於一個記錄,它將通過地址傳遞,而不是複製其內容,所以當然,速度增益可能相當大。但是在字符串參數的上下文中,引用計數(和所有相關的)是AFAIK的唯一區別。 –