簡體   English   中英

Delphi編譯器IntToStr()和Integer.ToString()之間的區別?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM