[英]Fastest way of converting integer to string in java
每次必須將int
轉換為String
我都會選擇""+a
或Integer.toString(a)
。 現在我想知道哪種方法更快,因此我編寫了一個簡單的基准測試,該函數調用function_1,function_2和function_3 10000000次,並打印處理這些函數所需的時間。 功能如下:
public static String i="";
public static String j="";
public static String k="";
public static void function_1()
{
i=Integer.toString(getOne());
}
public static void function_2()
{
j=""+1;
}
public static void function_3()
{
j=""+getOne();
}
public static int getOne()
{
return 1;
}
輸出為:
Benchmarking starting...
Executing function_1 10000000 time(s)...
Done executing function_1 in 476 ms.
Executing function_2 10000000 time(s)...
Done executing function_2 in 8 ms.
Executing function_3 10000000 time(s)...
Done executing function_3 in 634 ms.
Benchmarking complete!
我認為function_2是如此之快,因為它被編譯為
public static void function_2()
{
j="1";
}
為了避免這種情況,我改用了功能getOne()
。 但是這是有趣的部分(對我而言):必須不使用Object
的原始toString
方法(在這種情況下為Integer.toString(1)
因為int
是原始的)編譯function_3
。 我的問題是:編譯器實際上是如何威脅""+1
因此它比調用Integer.toString(1)
慢?
""
和1
在編譯時是已知的。 這就是為什么在轉換為字節碼時在function_2
中將"" + 1
真正替換為"1"
。
getOne()
結果在編譯時未知,因此串聯將在運行時完成。 但是,由於串聯(+)效率不高,因此編譯器可能會將其更改為基於StringBuilder.append()
的實現。
不相信我嗎? 嘗試: javap -c ClassName.class
,您將看到類似以下內容:
public static void function_2();
Code:
0: ldc #39 // String 1
2: putstatic #16 // Field j:Ljava/lang/String;
5: return
public static void function_3();
Code:
0: new #42 // class java/lang/StringBuilder
3: dup
4: invokespecial #44 // Method java/lang/StringBuilder."<init>":()V
7: invokestatic #28 // Method getOne:()I
10: invokevirtual #45 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
13: invokevirtual #49 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
16: putstatic #16 // Field j:Ljava/lang/String;
19: return
function_2()
僅具有一個字符串“ 1”,而function_3具有所有這些方法調用以及內部的其他StringBuilder :)
請記住,運行時可能會進行一些優化,但是此行為是JVM,並且取決於配置。
我在10,000,000次迭代中測試了以下函數:
public static void no_func_maybe_constant()
{
j= "" + 1;
}
public static void no_func_no_constant()
{
j = "";
j = j + 1;
}
public static void yes_func_maybe_constant()
{
j = "" + getOne();
}
public static void yes_func_no_constant()
{
j = "";
j = j + getOne();
}
我的結果:
no_func_maybe_constant Took 0.028058674s
no_func_no_constant Took 1.449465242s
yes_func_maybe_constant Took 1.275561897s
yes_func_no_constant Took 1.263362257s
不調用函數和調用函數之間的差異確實可以忽略不計,因此在"" + 1
的情況下似乎確實在進行一些編譯時常數計算。 有趣的是,沒有功能有時會花費更少的時間...
2與3之差可能是由於必須調用方法來獲取整數。 當您調用方法時,它會創建一個新的激活記錄,從而使調用堆棧復雜化,因此這里將進行更多的操作,除非JVM的JIT能夠將靜態函數調用僅內聯到單個返回值(幾乎肯定不會在這里發生)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.