¿Por qué el perro String.format de android es lento?

Implementaba una actividad de ListView con vistas dibujadas personalizadas y tenía el código siguiente:

@Override public void onDraw(Canvas canvas) { super.onDraw(canvas); .... canvas.drawText(String.format("%02d: %dx%d", position, w, h), 10, 15, cached_paint); } 

Casi nada más en el método onDraw, por lo que me estaba volviendo loco por qué el desplazamiento era tan pobre. Por casualidad he cambiado el parámetro drawText para no utilizar String.format y de repente el desplazamiento fue seda mantequilla de nuevo. De hecho, lo siguiente es prácticamente lo mismo pero funciona bien:

 canvas.drawText("" + position + ": " + w + "x" + h, 10, 15, cached_paint); 

Estoy atónito. ¿Por qué este último es más rápido que llamar a String.format? Esperaría que la concatenación de objetos generara más objetos intermedios y, en general, el rendimiento de basura, pero he encontrado exactamente lo contrario. De hecho, al ejecutar con String.format estaba recibiendo muchos mensajes de asignación / desasignación desde el vm.

Entonces, ¿por qué String.format es tan lento cuando aparentemente podría ser más rápido (al menos cuando viene de otros lenguajes de programación donde la creación de objetos es cara)?

La concatenación de cadenas con + no genera muchos objetos intermedios; Básicamente un StringBuffer y su matriz de caracteres internos (que podría obtener reasignado si se queda sin capacidad). Oh, y la cuerda cuando es a través de la concatenación.

Además, con + , la mayor parte del trabajo de analizar los tipos de datos de los objetos que entran en la cadena se realiza en tiempo de compilación. Con String.format, que se realiza en tiempo de ejecución. Para colmo, cada tipo primitivo que pasa a String.format necesita ser autoboxed, lo que genera mucho más objetos.

Estoy atónito.

¿Por qué?

¿Por qué este último es más rápido que llamar a String.format?

Porque está escrito en Java. %02d: %dx%d no es Java. Eso tiene que ser analizado cada vez y las reglas ejecutadas cada vez. Esas reglas se ejecutan en Java, a través de java.util.Formatter .

Ahora, String.format() podría ser optimizado reemplazándolo con una implementación de código nativo (C / C ++), pero creo que varargs y JNI se ponen desordenados.

Esperaría que la concatenación de objetos generara más objetos intermedios y, en general, el rendimiento de basura, pero he encontrado exactamente lo contrario. De hecho, al ejecutar con String.format estaba recibiendo muchos mensajes de asignación / desasignación desde el vm.

Eso sería porque String.format() es bastante complejo y se implementa en Java.

Para obtener el mejor rendimiento, puede crear un formateador desde el paquete java.text y almacenarlo en caché.

 final static DecimalFormat myFormat = new DecimalFormat("###"); @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); .... canvas.drawText(myFormat.format(w) + "x" + myFormat(h)); } 

Para un rendimiento aún mejor, puede utilizar una concatenación de cadenas más rápida. Pero eso es un tipo diferente de optimización, y fuera de tema para esta pregunta.

  • Las imágenes de gridview de Android en caché, en las imágenes de desplazamiento se repiten antes de ser reemplazadas
  • Rendimiento de Scala para Android
  • La respuesta de Json es un android muy lento
  • ¿Por qué Android prefiere las clases estáticas?
  • ¿Cuáles son los posibles problemas de rendimiento en el uso de python over java para el desarrollo de aplicaciones para Android?
  • Edittext Mensaje de error de validación en android?
  • Android WebView causa la violación de StrictMode
  • Hilo de fondo que bloquea la interfaz de usuario durante varios segundos
  • El proveedor de contactos de Android sólo obtiene contactos telefónicos con todos los correos electrónicos
  • Posible BUG en Android Clase ImageDownloader: sHardBitmapCache NO estática cuando debería ser?
  • Android: RunOnUiThread vs AsyncTask
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.