De los dos fragmentos que has publicado, no me gustaría a decir. Estoy de acuerdo con Will en que es casi irrelevante en el rendimiento general de su código, y si no lo es, puede hacer el cambio y determinar por sí mismo cuál es el más rápido para sus datos con su JVM en su hardware.
Dicho esto, es probable que el segundo fragmento sea mejor si convierte primero la Cadena en una matriz de caracteres, y luego realiza sus iteraciones sobre la matriz. Si lo hiciera de esta manera, realizaría la tara de una sola vez (convirtiendo a la matriz) en lugar de cada llamada. Además, puede pasar la matriz directamente al constructor de cadenas con algunos índices, que es más eficiente que tomar un de una matriz para pasarlo individualmente (que luego se convierte en una matriz de un carácter):
String s = "abcdefg";
char[] chars = s.toCharArray();
for(int i = 0; i < chars.length; i++) {
newFunction(String.valueOf(chars, i, 1));
}
Pero para reforzar mi primer punto, cuando miras lo que realmente estás evitando en cada llamada de String.charAt()
, son dos controles de límites, un (booleano) booleano O, y una adición. Esto no hará ninguna diferencia notable. Tampoco es la diferencia en los constructores de cadenas.
Básicamente, ambos modismos están bien en términos de rendimiento (ninguno de los dos es inmediatamente ineficiente) por lo que no deberías perder más tiempo trabajando en ellos a menos que un generador de perfiles demuestre que esto consume una gran parte del tiempo de ejecución de la aplicación.Y aun así, es casi seguro que obtendrás más mejoras de rendimiento al reestructurar tu código de soporte en esta área (por ejemplo, tener newFunction
tomar toda la cadena en sí); java.lang.String está bastante bien optimizado en este punto.
Como esto va a pasar una cadena, necesita cambiar ligeramente las pruebas en la primera prueba. {char [] s = "abcdefg" .toCharArray();} debería estar dentro del bucle, o incluso mejor (para evitar una optimización inteligente por parte de la JVM, ponga todo el bucle y .toCharArray() dentro de una función separada). Es importante medir todos los gastos generales iniciales, así como los costos de los bucles. Especialmente dado que el rendimiento podría realmente dar una propina de uno a otro según la longitud de la cuerda. Por lo tanto, probar varias longitudes de picaduras también es importante. – MatBailie
+1 por responder la pregunta. – gustafc
Se movió "s" dentro del bucle y se agregó un assert() para evitar la optimización de JVM de newFunction(). Por supuesto ahora es más lento, pero las medidas relativas siguen siendo las mismas. Mi punto es simplemente que hay posibilidades de optimización si el problema se conoce exactamente. El objetivo no es cambiar qué función utilizar para una determinada operación, sino ver la operación en un nivel superior para obtener mejoras, p. mediante el almacenamiento en caché – mhaller