Ogni volta che dovevo convertire unin un String
, ho scelto ""+a
o Integer.toString(a)
. Ora mi chiedevo quale fosse la strada più veloce, così ho scritto un semplice benchmark che chiama function_1, function_2 e function_3 10000000 volte e stampa quanto tempo ci vuole per elaborare le funzioni. Qui ci sono le funzioni:Il modo più veloce di convertire i numeri interi in stringa in java
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;
}
l'output è:
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!
Credo function_2 è così veloce, perché è compilato come
public static void function_2()
{
j="1";
}
in modo da evitare che, ho usato il funzione invece getOne()
. Ma ecco la parte interessante (per me): function_3
deve essere compilato senza utilizzare il metodo originale toString
di Object
(in questo caso Integer.toString(1)
perché int
è primitivo). La mia domanda è: in che modo il compilatore minaccia effettivamente ""+1
quindi è più lento quindi chiama Integer.toString(1)
?
Hai considerato il bytecode? Inoltre, i micro-benchmark sono, in generale, inutili. Le cose potrebbero anche accadere a livello di JIT. –
'" "+ 1' è il * più veloce * (di molto) in base a quei numeri. E, sembra solo intuitivo che una funzione specializzata sia [leggermente] più veloce di chiamare una funzione ed eseguire una stringa concatenando il risultato. –
Se osservi il bytecode probabilmente troverai 'function_3' usa un' StringBuilder 'mentre' function_1' no. E internamente, 'StringBuilder' chiamerà' String.valueOf() '. – parsifal