Para mejorar su rendimiento, he estado perfilando una de mis aplicaciones con la muestra VisualVM, utilizando un período de muestreo mínimo de 20 ms. Según el generador de perfiles, el hilo principal gasta casi un cuarto de su tiempo de CPU en el método DecimalFormat.format()
.¿Una alternativa más rápida a DecimalFormat.format()?
estoy usando DecimalFormat.format()
con el patrón 0.000000
"convertir" double
números a una representación de cadena con exactamente seis dígitos decimales. Sé que este método es relativamente caro y es llamado muchas veces, pero todavía estaba algo sorprendido por estos resultados.
¿Hasta qué punto son precisos los resultados de dicho generador de perfiles de muestreo? ¿Cómo podría verificarlos? ¿Preferiblemente sin recurrir a un perfilador de instrumentos?
¿Existe una alternativa más rápida a
DecimalFormat
para mi caso de uso? ¿Tendría sentido implementar mi propia subclaseNumberFormat
?
UPDATE:
creé una micro-punto de referencia para comparar el rendimiento de los tres métodos siguientes:
DecimalFormat.format()
: SingleDecimalFormat
objeto reutilizados varias veces.String.format()
: Múltiples llamadas independientes. Internamente este método se reduce apublic static String format(String format, Object ... args) { return new Formatter().format(format, args).toString(); }
tanto que esperaba su rendimiento sea muy similar a
Formatter.format()
.Formatter.format()
: SoloFormatter
objeto reutilizado varias veces.Este método es un poco incómoda -
Formatter
objetos creados con el constructor por defecto anexar todas las cadenas creadas por el métodoformat()
a unStringBuilder
objeto interno, que no es adecuadamente accesible y por lo tanto no se pueden borrar. Como consecuencia, múltiples llamadas aformat()
crearán una concatenación de todas las cadenas resultantes.Para solucionar este problema, proporcioné mi propia instancia de
StringBuilder
que borré antes de su uso con una llamadasetLength(0)
.
Los resultados donde interesante:
DecimalFormat.format()
era la línea de base en 1.4us por llamada.String.format()
fue más lento en un factor de dos a 2.7us por llamada.Formatter.format()
también fue más lento en un factor de dos a 2.5us por llamada.
En este momento parece que DecimalFormat.format()
sigue siendo la más rápida entre estas alternativas.
+1 Estaba a punto de escribir algo yo mismo: este fragmento de código podría ser un buen punto de partida. – thkala
Finalmente escribí un formateador usando mi propio algoritmo y es aproximadamente cuatro veces más rápido que 'DecimalFormat' para el subconjunto de funcionalidad que necesito. Creo que todavía hay margen de mejora, ya que en realidad no bajé al nivel de agregar dígitos individuales. Aceptaré esta respuesta ya que es la única que contiene código utilizable. – thkala
Gran trabajo Peter. He reutilizado tu código para crear el formateador rápido 'double' e incluso twiece faster' String' (contiene valor doble). – dantuch