Bienvenido, les saluda Luis y en esta ocasión les traigo este nuevo tutorial.
Índice
Conoce el precio de las enumeraciones antes de usarlas
De vez en cuando, al desarrollar aplicaciones, es posible que haya utilizado enumeraciones. Son útiles. Pero cuando los usó, es posible que no haya conocido el impacto completo de las enumeraciones. Las enumeraciones son muy convenientes pero, desafortunadamente, pueden ser dolorosas cuando se trata de tamaño y velocidad de la memoria. Exploremos cómo las enumeraciones afectan el rendimiento y cómo dejamos de usarlas.
¿Qué es una enumeración?
Una enumeración en Java es un tipo de datos que contiene un conjunto fijo de constantes.
Es un tipo de datos especial que permite que una variable sea un conjunto lleno de constantes predefinidas. Su variable debe ser igual a uno de los valores que se le han predefinido.
¿Por qué utilizamos Enums?
Usamos enumeraciones cuando una variable solo puede tomar un valor de un conjunto de valores posibles. Consideremos un ejemplo:
public enum Fruits {Apple, Bannana, Grape, Mango}
Ahora, la enumeración nombrada Fruits
solo puede tener un valor, y no puede haber otro valor que no sea uno de estos que se han definido.
Pero en el caso de que usemos un entero o una constante de cadena, puede haber una posibilidad de pasar constantes no válidas. Entonces, para evitar estos errores constantes inválidos y aumentar la verificación en tiempo de compilación , generalmente usamos una enumeración.
El precio de las enumeraciones
Los valores de enumeración ocuparán más memoria en comparación con una constante int. Agregar una sola enumeración aumentará el tamaño del archivo DEX final aproximadamente 13 veces cuando sea una constante entera.
Esto se debe a que cada valor en una clase de enumeración se trata como un objeto, y cada valor necesitará algo de memoria de pila para hacer referencia al objeto. Esto devora el espacio geap disponible.
Cuantas más enumeraciones tengamos en nuestra aplicación, más espacio se consumirá.
Es posible que ni siquiera sepamos que la enumeración está afectando el rendimiento de nuestra aplicación. Tal vez escribir una o dos clases de enumeración no tenga un gran impacto en nuestra aplicación. Pero si está usando algunas clases de enumeración y las bibliotecas incluidas en su aplicación usan otras clases de enumeración, la combinación de todas estas enumeraciones podría tener un impacto considerable en su aplicación que podría aumentar el tamaño del archivo, así como también afectar el rendimiento.
A tener en cuenta: Los redactores del equipo de la plataforma central recomiendan encarecidamente no utilizar enumeraciones en ninguna parte del código que escriben.
Solución
Android admite una variedad de anotaciones a través de la Biblioteca de compatibilidad de anotaciones. Puede acceder a la biblioteca a través del android.support.annotation
paquete. Esta biblioteca tiene anotaciones. Estas anotaciones garantizan que un parámetro, valor de retorno o campo en particular haga referencia a un conjunto específico de constantes. También permiten la finalización del código para ofrecer automáticamente las constantes permitidas.TypeDef
@IntDef
y @StringDef
son dos anotaciones constantes que se pueden usar en lugar de enumeraciones para las constantes int y string que brindarán seguridad en el tiempo de compilación. Estas anotaciones nos ayudarán a verificar las asignaciones de variables, como lo haría una enumeración, en tiempo de compilación.
Cómo utilizar las anotaciones
Entendamos esto usando un ejemplo.
Tenemos una Fruit
clase con un conjunto de constantes int. Entonces, mientras creamos el objeto, necesitamos pasar el valor del tipo int del conjunto disponible. Pero en mi método principal, estaba pasando un valor que no estaba en el conjunto de constantes, lo que puede llevar a una situación problemática. No hay seguridad de tipos en el siguiente fragmento de código.
public class Fruit { public static final int APPLE = 0; public static final int BANNANA = 1; public static final int GRAPE = 2; public static final int MANGO = 3;public Fruit(int fruit) { System.out.println("Fruit Selected:" + fruit); }public static void main(String[] args) { //Passing Invalid value Fruit fruit = new Fruit(4); } }
Una implementación de código similar usando enumeraciones es la siguiente:
public class EnumFruit { public EnumFruit(Fruit fruit) { . System.out.println("Fruit selected is:" + fruit); }public enum Fruit { APPLE, BANNANA, GRAPE, MANGO }public static void main(String[] args) { EnumFruit enumFruitInstance = new EnumFruit(Fruit.APPLE); }}
Agregue la dependencia de anotaciones de soporte en el nivel de la aplicación build.gradle
:
dependencies { implementation 'com.android.support:support-annotations:28.0.0' }
Declare las constantes y @IntDef
para estas constantes:
public class AnnotationFruit { public static final int APPLE = 0; public static final int BANNANA = 1; public static final int GRAPE = 2; public static final int MANGO = 3; public AnnotationFruit(@Fruit int fruit) { System.out.println("Fruit Selected is :" + fruit); }@IntDef({APPLE, BANNANA, GRAPE, MANGO}) @Retention(RetentionPolicy.SOURCE) public @interface Fruit {}public static void main(String[] args) { AnnotationFruit annotationSeason = new AnnotationFruit(GRAPE); } }
En el ejemplo anterior, Typedef
uso de anotaciones:
@interface
para declarar el nuevo tipo de anotación enumerado- los
@IntDef
y@StringDef
anotaciones, junto con@Retention
, son necesarios para definir el tipo enumerado
los @Retention(RetentionPolicy.SOURCE)
anotación le dice al compilador que no almacene los datos de anotación enumerados en el .class
expediente.
Los setters y getters se pueden definir de la siguiente manera:
// Decorate the target methods with the annotation @Fruit public abstract int getFruitName();// Attach the annotation public abstract void setFruitName(@Fruit int fuitValue);
Si Proguard está configurado correctamente, puede optimizar las enumeraciones a valores int en nuestro nombre en algunas o muchas situaciones. Por tanto, es posible que no tengamos que preocuparnos.
Conclusión
Las enumeraciones agregan al menos 2 veces más bytes al tamaño total de APK que las constantes simples y pueden usar aproximadamente 5-10 veces más RAM que las constantes equivalentes.
Entonces, si desea que su aplicación sea eficiente en memoria y rendimiento, intente evitar enumeraciones en su código.
Referencias:
Añadir comentario