Tuesday, July 12, 2011

cursor.getString() vs cursor.copyStringToBuffer()

Some days ago cyrilmottier posted a blog post about ListView's tip and tricks.
In one of his tips he mentions the following:
CharArrayBuffer: Developers are regularly using the getString() method on the Cursor. Unfortunately, it implies creating String objects. These objects are likely to be garbaged once the user starts scrolling. In order to prevent object creation and consequently garbage collection freezes, it is possible to use a CharArrayBuffer that consists on copying data from the Cursor to a raw array of char that will be directly used by our TextViews. Instead of having to create aString object, we will hence reuse a CharArrayBuffer.
My first thought was: Oh my! I am using getString() everywhere! We had some performance issues in the past with a Gallery so it was a great place to start fixing the code.
Yesterday evening I modified the adapter's code to use CharArrayBuffer instead of getString(). When I tested the app it felt slower than before and very blocky. I went to sleep.


Traceview:

Today evening I decided starting from the scratch, but instead of using my app I decided to create a toy app. I stole some code from @vogella and start testing.

You can download the app from this link.
My first test was with the traceview tool:



In the screenshot you see two instances of the traceview tool analyzing the bindView method.
Over the top, you can see
withoutFix.trace (the one using the cursor.getString() method) and below the withFix.trace (which is using the cursor.copyStringToBuffer).

Another thing I took some time trying to understand is this:


Conclusions so far:
* Using cursor.copyStringToBuffer() seems to run the bindView method faster than cursor.getString().
* cursor.getString() is faster than cursor.copyStringToBuffer()

The difference is not much so I wouldn't take care of keeping the fix. The code looks clearer with the getString() method.


MAT:
But wait, let's give it a try to the Memory Analyzer (MAT).
Note: After hearing @dubroy's talk at the googleIO 2011 I wanted to do something like this :)

@dubroy also wrote an article for the Android Developers blog called "Memory Analysis for Android".

What I did was comparing two heaps from both options.




Objects #0 and Shallow Heap #0 are for the cursor.getString() version and
Objects #1 and Shallow Heap #1 are for the cursor.copyStringToBuffer().

Not much to say here.
* The getString() versions has less String objects.
* The copyStringToBuffer uses more heap. (I use three new CharArrayBuffer(128))


Final conclusion:

I am not an expert using this tools but, from what I have tested, I couldn't notice a performance improvement when using cursor.copyStringToBuffer().

What do you guys think?

UPDATE:

I had the following conversation with cyrilmottier over twitter:
cyrilmottier: The actual benefit is you will reduce garbage collection to a minimum. This is less useful in Android 2.3 or higher.

2.3 introduced a generational GC. Hence, CharArrayBuffer is probably more useful on old Android versions.

me: It makes sense. I will keep the getString() calls, knowing that I have the buffer if I need to improve memory usage.

Sunday, July 10, 2011

Android market: Books y Movies en Argentina?

Ayer estuve browseando el android market desde la xoom y se me dio por entrar a Books y Movies. Por suerte ya no son secciones vacías. Veamos qué se puede hacer!

Books
Por ahora se puede browsear los libros,


pero cuando querés entrar en el detalle de alguno muestra un error:


Movies
A diferencia de los libros, las películas muestran otra información.
La pantalla principal se ve así:


El filtrado de las películas todavía no existe. No puedo buscar por año, ni por precio.
En Comedias encontré una que no había visto. Matchstick Men. La pantalla del detalle fue la siguiente:


El problema ocurrió cuando la quise comprar. Lamentablemente no aceptó mi tarjeta de crédito:



GoogleTV
Todavía no hay novedades de honeycomb para googleTV. Aparecieron dos updates pero ninguna interesante.
La versión de googleTV que tengo ahora no permite acceder al market pero hay dos opciones que permiten acceder a Netflix y a Amazon Video.

  • Netflix no entra diciendo que todavía no está en Argentina.
  • Amazon Video te permite browsear pero cuando querés comprar te dice que necesitás tarjeta de crédito de EE.UU. y domicilio de allá.

Conclusión
Existe un pequeño avance desde la última vez que probé, pero, por ahora, seguimos lejos de poder alquilar una película por internet. Netflix ya anunció que va a abrir en Argentina, así que a esperar un poco más :)