[英]Delphi compiler difference between IntToStr() and Integer.ToString()?
將Integer
轉換為string
時, IntToStr()
和Integer.ToString()
之間的基本區別是什么。 哪一個更快?
var
VarInt: integer;
VarStr: string;
begin
VarInt := 5;
VarStr := IntToStr(VarInt);
VarStr := VarInt.ToString;
end;
免責聲明 :以下文本包含僅適用於Delphi 10.2.1(以及10.2.2)的詳細信息,這些內容似乎使內聯和RVO更糟糕:
編譯器生成的代碼確實不同(無論編譯器版本如何),因為您在查看反匯編窗口時可以輕松看到。
讓我們來看看這個例程:
procedure Main;
var
i: Integer;
s: string;
begin
i := 0;
s := IntToStr(i);
s := i.ToString;
end;
現在讓我們運行它並查看反匯編窗口以檢查編譯器生成的代碼:
這就是你在Delphi 10.1中得到的:
Project1.dpr.14: s := IntToStr(i);
00419810 8D55F8 lea edx,[ebp-$08]
00419813 8B45FC mov eax,[ebp-$04]
00419816 E80DA4FFFF call IntToStr
Project1.dpr.15: s := i.ToString;
0041981B 8D55F4 lea edx,[ebp-$0c]
0041981E 8B45FC mov eax,[ebp-$04]
00419821 E802A4FFFF call IntToStr
00419826 8D45F8 lea eax,[ebp-$08]
00419829 8B55F4 mov edx,[ebp-$0c]
0041982C E843D2FEFF call @UStrLAsg
這就是你得到的10.2.1(以及10.2.2):
Project1.dpr.14: s := IntToStr(i);
00419B04 8D55F8 lea edx,[ebp-$08]
00419B07 8B45FC mov eax,[ebp-$04]
00419B0A E8C5A2FFFF call IntToStr
Project1.dpr.15: s := i.ToString;
00419B0F 33C0 xor eax,eax
00419B11 55 push ebp
00419B12 68499B4100 push $00419b49
00419B17 64FF30 push dword ptr fs:[eax]
00419B1A 648920 mov fs:[eax],esp
00419B1D 8D55F4 lea edx,[ebp-$0c]
00419B20 8B45FC mov eax,[ebp-$04]
00419B23 E8ACA2FFFF call IntToStr
00419B28 8D45F8 lea eax,[ebp-$08]
00419B2B 8B55F4 mov edx,[ebp-$0c]
00419B2E E805D0FEFF call @UStrLAsg
00419B33 33C0 xor eax,eax
00419B35 5A pop edx
00419B36 59 pop ecx
00419B37 59 pop ecx
00419B38 648910 mov fs:[eax],edx
00419B3B 68509B4100 push $00419b50
00419B40 8D45F4 lea eax,[ebp-$0c]
00419B43 E8D4CCFEFF call @UStrClr
00419B48 C3 ret
00419B49 E9CEC3FEFF jmp @HandleFinally
00419B4E EBF0 jmp $00419b40
現在百萬美元的問題是,那里有什么額外的指示?!
您可以在兩個編譯器中看到的額外指令是缺少所謂的返回值優化的結果。 您可能知道編譯器會將托管類型(如字符串)的函數結果視為隱藏的var參數。 現在,當編譯器執行內聯時,它不會消除此參數,而是直接將s
變量傳遞給IntToStr
就像直接調用它一樣。 它保留了一個臨時變量,用於傳遞給IntToStr
,然后將該變量分配給s
(這就是call @UStrLAsg
你看到IntToStr
調用后有3行)。
正如我上面提到的那樣,似乎在10.2或10.2.1中有一個回歸,他們在內聯調用之后改變了一些關於臨時變量清理的東西(這是之前和之后的額外指令)。
報告為RSP-19439 。
未完待續 ...
沒有區別。
Int.ToString
的定義如下:
function TIntHelper.ToString: string; inline;
begin
Result := IntToStr(Self);
end;
因為它是內聯的,所以它只會轉換為IntToStr(Int)
。
添加了var.action
方法,使運行時庫(RTL)更適合Java和C#程序員。 這對於人們可能接觸過Java的移動平台尤為重要。
這樣做的一個主要好處是功能更容易被發現。 你只需輸入VarInt.
並且自動完成將顯示所有可用選項。 如果您不了解IntToStr
已經很難找到它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.