Optimización de rendimiento de dispositivos J2ME

LIBP-0076 (Libro de pautas)

Pautas

TítuloCarácter
Optimización para la mantenibilidadRecomendada
Tamaño de los MIDletsRecomendada
Optimización de la velocidadObligatoria
Mejora de las operaciones gráficasObligatoria
Recolector de BasuraObligatoria

Optimización para la mantenibilidad

Para conseguir un código mantenible, debemos de intentar que sea lo mas sencillo posible y fácil de comprender. Para conseguir este objetivo , lo mejor es diseñar los MIDlets lo más simple posible creando interfaces de usuario sin un gran numero de comandas y componentes.

Tamaño de los MIDlets

Es recomendable hacer los MIDlets lo mas pequeño posible, sin alterar la funcionalidad

Para optimización el tamaño del MIDlet lo que debemos hacer es que el tamaño de las clases resultantes sea lo más pequeño posible. La piedra angular de esta optimización es la reutilización del código, cuya base es la herencia. Otro punto a considerar son los recursos usados por el MIDlets y los datos que gestiona. Para reducir el uso de memoria, podemos usar alguna de las siguientes técnicas:

  • Evitar el uso de objetos siempre que sea posible
  • Cuando usamos objetos, debemos reciclarlos siempre que sea posible
  • Limpiar los objetos explícitamente cuando finalicemos de usarlos. El garbage collector de J2ME no es del todo eficiente, ya que su prioridad es muy baja
  • Usar un ofuscador. Los ofuscadores reducen de forma considerable el tamaño del jar a distribuir
  • Tener los recursos optimizados para el terminal. No debemos olvidar que los recursos son incluidos dentro del jar de distribución

Optimización de la velocidad

La optimización de la velocidad de ejecución del MIDlet es la más importante y es lo que debemos tener presente en primer lugar. Para mejorar la velocidad de ejecución del código debemos de considerar:

  • Eliminación de Evaluaciones innecesarias
// El siguiente código:

for (int i=0; i<size(); i++)
   a = (b + c) / i ;

// Puede ser optimizado de la siguiente forma:

int tmp = b + c;
int s = size();
for (int i=0; i<s; i++)
    a = tmp / i;
  • Eliminar subexpresiones comunes
// El siguiente código:

b = Math.abs(a) * c;
d = e / (Math.abs(a) + b);

// Puede ser optimizado de la siguiente forma:

int tmp = Math.abs(a);
b = tmp * c;
d = e / (tmp + b);
  • Aprovechar las variables locales
// El siguiente código:

for (int i=0; i<1000; i++)
   a = obj.b * i;

// Puede ser optimizado de la siguiente forma:

int localb = obj.b;
for (int i=0; i<1000; i++)
    a = localb * i;
  • Expandir los bucles
// El siguiente código:

for (int i=0; i<1000; i++)
    a[i] = 25;

// Puede ser optimizado de la siguiente forma:

for (int i=0; i<100; i++){
   a[i++] = 25;
   a[i++] = 25;
   a[i++] = 25;
   a[i++] = 25;
   a[i++] = 25;
   a[i++] = 25;
   a[i++] = 25;
   a[i++] = 25;
   a[i++] = 25;
   a[i++] = 25;
}

Mejora de las operaciones gráficas

Cuando usamos gráficas de bajo nivel, debemos tener mucho cuidado con la forma en que se realizan estas operaciones, ya que un funcionamiento lento, echará a perder cualquier aplicación. Una buena política es repintar sólo aquella parte de la pantalla que ha de cambiar, en lugar de repintar toda la pantalla. El siguiente método nos permite hacer esto de forma sencilla:

Canvas.repaint(int x, int y, int width, int height);

Otro buen sistema de optimización de procesos gráficos es la utilización de imágenes off-screen. Este sistema es especialmente adecuado cuando nuestras pantallas cambian poco entre repintados. En este caso podemos dibujar sobre una imagen en memoria y luego mostrar en el método paint esta imagen.

Por último, sólo decir que es muy útil la utilización del método serviceRepaints. Este método fuerza el repintado de la pantalla de manera inmediata. Cuando tenemos una interacción constante con el usuario, este método es esencial para que el usuario perciba que el sistema reacciona a sus comandos. Sin este método, el repintado podría tardar el tiempo suficiente como para que se sobrepongan varios comandos del usuario y este no tenga una buena experiencia en la utilización de la aplicación.

Recolector de Basura

Debemos evitar la creación de objetos innecesarios, ya que el proceso que se encarga de recoger los objetos no útiles y destruirlos, tiene una prioridad muy baja. Debemos reutilizar los objetos siempre que sea posible.

Debemos evitar ,en la medida de lo posible, los objetos inmutables, es decir, aquellos objetos cuyo estado no puede ser modificado después de su creación. Este tipo de objetos suelen ser inútiles una vez que su valor inicial ya no es necesario y cuando se necesita un nuevo valor, habrá que crear un nuevo objeto.