Lejos del academicismo y las buenas maneras, cuando tenemos que liarnos a programar con prisas (o “picar código como un loco”), el rendimiento es algo que nos importa poco menos que nada. Tenemos máquinas y servidores con potencia suficiente para mover código altamente ineficiente. Ésta falta de eficiencia se nota preocupantemente en una aplicación funcionando en un dispositivo móvil. Estamos hablando de equipos con procesador de bajo rendimiento y memoria limitada, lo que facilita enormemente la saturación de la memoria o la carga excesiva de proceso y, por lo tanto, lentitud.
¿Alguna solución para mejorar el rendimiento? Bueno, repasemos algunos consejos y pautas a seguir para programar en Compact Framework de forma que nuestro código no supongo una patada en el núcleo de proceso al dispositivo móvil o a la memoria del mismo. Resumiré algunas, las que considero más importantes :
- Evitar los métodos virtuales : Los métodos virtuales (virtual) son hasta un 40% más lentos en ejecución que un método estático (static) o un método de instancia corriente. Esto se debe a que la Compact Framework interpreta directamente las llamadas en lugar de indizarlas en un VTABLE para evitar el coste de mantenimiento de la misma en memoria y ahorrar el espacio que supondrían ciertas llamadas a métodos que nunca se van a realizar. Cuando se tiene que hacer una llamada a un método virtual se recorre la jerarquía de clases, lo cual, aunque se mantenga una caché de llamadas, es un tanto engorroso. Tampoco pretendo decir que los métodos virtuales sean una tara importante para el rendimiento… lo serán cuando se trate de método que sean llamados con frecuencia en la aplicación.
- Evitar el uso de propiedades en las clases : Si empleamos las propiedades para hacer asignaciones y devoluciones de campos privados de la clase sin más… mejor que declaremos como público (public) el campo. Las llamadas de asignación (set) y devolución (get) de las propiedades son métodos y requieren llamadas, lo cual será menos óptimo que acceder directamente al campo.
- Emplear variables de 32 bits : El JIT de la Compact Framework empleará los registros de la CPU cuando le sea posible para almacenar las variables locales y los parámetros de los métodos que sean de 32 bits. También se puede hacer esto con variables de 8 o 16 bits, pero en ocasiones resulta engorroso por la necesidad de realizar alguna que otra conversión. Al tener ya asignado registro en la memoria de la CPU, será mejor reutilizar una variable ya declarada que declarar una nueva.
- Efectuar llamadas manuales al colector de basura : El colector de basura o GC solo entre en acción cuando se detecta que el montón que se emplea en gestión de memoria está lleno ante la inserción de un nuevo elemento en memoria, cuando una aplicación va a finalizar o cuando se fuerza su ejecución mediante el método Collect(). Conviene emplear la última técnica citada para obligar a que el GC libere la memoria de aquellos objetos que se han dejado de utilizar. Conviene que en todas las clases implementemos la interfaz IDisposable. Recordemos que las invocaciones al método Dispose() no implican que el objeto sea completamente eliminado de la memoria, de ahí que sea conveniente forzar al GC. Conviene recordar que el GC se ejecuta en segundo plano y que su pesadez dependerá directamente de la cantidad de referencias a eliminar así como del tamaño del montón.
- Evitar emplear bucles foreach : Este tipo de bucles que tan cómodos resultan al recorrer una colección resultan pesados en ejecución al tener que realizar varias llamadas a métodos de la clase IEnumerator. Siempre que podamos, debemos emplear bucles for o while.
Esto refiere solo a algunos puntos a tener en cuenta. Por supuesto, hay muchísimas más técnicas y cuestiones a tener en cuenta. Os dejo un par de enlaces como referencia :
.NET CF version 2.0 Performance and Working Set FAQ
Espero que le sirva de ayuda a alguien.