Diferencia entre el conmutador empaquetado y el interruptor escaso dalvik opcode

Quiero saber la diferencia entre el paquete de conmutación y escaso switch opcodes en dalvik. Por favor, si puede dar ejemplos. La explicación proporcionada por google no está claro para mí.

Conmutador empacado

Gracias.

Suena como si packed-switch es equivalente al tableswitch de tableswitch de Java, y sparse-switch al lookupswitch .

Un packed-switch usa una tabla de salto simple, indexada por la forma low + n , donde low es el valor de prueba más bajo entre las etiquetas de los case y n es la entrada al switch . Los valores de cada índice representan los desplazamientos de bytecode para cada case . Encontrar la dirección de salto correcta es una operación de tiempo constante.

Un sparse-switch usa una lista ordenada de pares clave-valor, donde cada clave es un valor de prueba de una etiqueta de case y los valores son desplazamientos de salto. Encontrar el objetivo de salto correcto para un lookupswitch requiere una búsqueda binaria en la clave, por lo que es una operación de tiempo logarítmico.

El compilador elegirá qué utilizar. Si las claves tienden a ser agrupadas o empaquetadas juntas, entonces un packed-switch (o, en términos de Java, un tableswitch ) se puede emitir eficientemente. Pero si las claves son escasas y el rango de valores ( high - low + 1 ) es grande, entonces usar una tabla de salto requeriría un gran bloque de bytecode, ya que todos los valores de ese rango deben existir en la tabla de salto independientemente de si Hay una etiqueta de case correspondiente. En estos escenarios, el compilador emitirá un sparse-switch lookupswitch ( lookupswitch ).

Curiosamente, los ingenieros de Dalvik optaron por nombrar estos opcodes de una manera que describe las distribuciones de claves para las cuales deberían ser utilizados, mientras que los ingenieros de Java eligieron nombres que describen las estructuras de datos conceptuales que los operandos de bytecode se asemejan.

Veamos algunos ejemplos. Considere el siguiente código Java, que producirá un tableswitch (y, cuando se convierta a Dalvik, un packed-switch ):

 static String packedSwitch(final int n) { switch (n) { case 5: return "Five"; case 3: return "Three"; case 1: return "One"; default: return "Other"; } } 

Conceptualmente, la carga útil para el opcode del packed-switch sería algo como esto:

Interruptor real

Como puede ver, es bastante compacto. Tres de las cinco ranuras apuntan a objetivos reales de case , con los dos restantes saltando al objetivo default . Pero, ¿y si nuestros valores de prueba estuvieran más extendidos?

 static String sparseSwitch(final int n) { switch (n) { case 500: return "Five Hundred"; case 300: return "Three Hundred"; case 100: return "One Hundred"; default: return "Other"; } } 

Si el compilador trató de emitir esto como un packed-switch , la carga útil se vería algo como esto:

Conmutador teórico

Observe cómo sólo tres de unos pocos centenares de ranuras apuntan realmente a las etiquetas del case del código original. El resto está allí simplemente para llenar la tabla de salto. No muy eficiente en el espacio, ¿verdad? Ése es porqué el compilador emitiría un sparse-switch , que tenga una huella mucho más compacta del bytecode para este ejemplo particular:

Interruptor disperso

Ahora, eso es mucho más razonable, ¿no crees? La desventaja, sin embargo, es que en vez de saber exactamente qué índice saltar a basado en la entrada, tenemos que realizar una búsqueda binaria en la tabla hasta que encontremos un valor de prueba correspondiente. Cuanto mayor es el interruptor, más significativo es el impacto en el rendimiento, aunque el efecto tiene una curva logarítmica.

  • Error de sintaxis: Insertar "}" para completar el bloque
  • Cambiar el tamaño de una ruta en el lienzo de Android
  • ¿Cómo realizar una solicitud DELETE sin tipo de devolución o devolución de llamada?
  • Calcular el tiempo estimado de descarga restante
  • Android: cómo obtener el día actual de la semana (lunes, etc ...) en el idioma del usuario?
  • El diseño de fragmentos de Android no se carga al mostrar un anuncio intersticial de Admob en OnCreateView
  • ¿Cómo instalar manualmente App Engine en Android Studio?
  • Usando el EventBus de Guava, ¿es posible ejecutar código de suscriptor en el subproceso que creó el bus?
  • Manera portable de garantizar que el campo del año de un DateFormat es solamente dos dígitos
  • Envío de mayúsculas a un TextEdit durante pruebas instrumentadas
  • Eclipse utiliza la variable PATH antigua para ejecutar el proceso de línea de comandos en la tarea Gradle?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.