¿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:
- Google Maps Android API v2 bloquea el subproceso de la interfaz de usuario
- ¿Cuál es la tasa de bits de lectura NFC efectiva usando comandos de APDU?
- Android: Ampliación del libro de contactos del usuario. Rendimiento ContentProvider vs Sqlite vs Lista en la memoria
- Android Remote methods (AIDL) vs Intents - rendimiento y uso de la batería
- ¿Por qué Xamarin.Forms es tan lento al mostrar algunas etiquetas (especialmente en Android)?
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)?
- Desplazamiento a través de ListView con algunas imágenes muy laggy
- Servicios WebSocket de Android que realizan varias conexiones
- ¿Puedo activar multidex en la compilación de depuración de Android solamente?
- Android TextureView / Dibujo / Rendimiento de la pintura
- En Android; ¿Es mejor aplicar un OnClickListener o usar android: onClick?
- Fondo animado con Libgdx
- Android: nesting FrameLayouts - ¿cuál es la sobrecarga de rendimiento exacto?
- Rendimiento de bucle ArrayList en ART (Android Runtime Environment)
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.
- ¿Hay una manera de ejecutar script SL4A desde un directorio en otro lugar?
- ¿Puede un IME (teclado virtual) obtener el nombre de la aplicación que lo usa?