簡體   English   中英

在Java中將整數轉換為字符串的最快方法

[英]Fastest way of converting integer to string in java

每次必須將int轉換為String我都會選擇""+aInteger.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.

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