¿Las funciones en línea de Kotlin son less costosas que las classs anónimas de Java?

Heads up: estoy escribiendo algo de esto de memory así que puedo tener algunos de los conceptos incorrectos.


Java tiene la capacidad de escribir una function anónima. Esto es útil cuando tienes una interfaz de escucha para algún tipo de evento. Como ejemplo:

button.setOnClickListener(new View.OnClickListener(View v) { @Override public void onClick(View v) { // handle the action here } }); 

El oyente anónimo se comstackrá como una class que se llama algo así como OnClickListener$1.class . Esta es una decisión de layout subyacente del lenguaje Java. Todo es un object, incluso funciones anónimas.

Esto se convierte en un problema cuando se quiere escribir una base de código más funcional. La gran cantidad de classs anónimas crea un gran recuento de classs, lo que puede ser un problema en plataforms restringidas como Android.

En Kotlin, las funciones son mucho más de primera class desde el punto de vista del código fuente. Mi pregunta es, ¿comstack Kotlin estas funciones hasta el código de bytes de manera más eficiente que Java con classs anónimas o me encontraré con los mismos problemas que el recuento de classs grandes en Java?

Gracias,

La respuesta corta es , las funciones en línea de Kotlin son bastante baratas.

Cuando se comstack una llamada de function en línea, las lambdas pasadas a la llamada se insertan en el cuerpo de la function, que a su vez está en línea en el sitio de la llamada. Esto permite que el comstackdor no genere classs o methods adicionales para los cuerpos lambda.

Compilación de una función en línea

Una de las diapositivas sobre Kotlin construye compilation por @yole . Desafortunadamente, encontré el logging solo en ruso . Las otras diapositivas también son de interés, puedes encontrar más acerca de lambdas no en línea allí.

En general, el código de Kotlin que usa funciones en línea con lambdas funciona más rápido que el código de Java idéntico con lambdas o Streams. Todo el enlace de código se realiza en time de compilation, y no hay sobrecarga de time de ejecución de las llamadas a methods virtuales, ni el aumento de methods count, lo cual es importante para Android.

La desventaja de una alignment excesiva es el crecimiento del tamaño del código: la parte común del bytecode de un cuerpo de function en línea realmente se duplica en los sitios de llamadas. Además, la internación complica la debugging, porque los numbers de línea y la stack de llamadas del código diferirán de lo que estaba en el file fuente. Aunque el soporte IDE puede ayudar aquí.

Te recomendaría que experimentes con funciones en línea tú mismo: puedes inspeccionar fácilmente el código de bytes resultante ; y, por supuesto, hacer una evaluación comparativa de sus casos de uso particulares donde el performance importa.

Kotlin tiene una palabra key en inline . Si usa esta palabra key, no solo alinea la function, sino que puede tratar el cuerpo lambda como si fuera solo un nivel de ámbito nested, para que pueda return de él.

Ejemplo (directamente de los documentos)

 fun foo() { inlineFunction { return // OK: the lambda is inlined } } 

Consulte los documentos para get más información:

https://kotlinlang.org/docs/reference/inline-functions.html

Editar:

Para aclarar su pregunta exacta sobre el performance, este es el primer párrafo de los documentos:

El uso de funciones de order superior impone ciertas penalizaciones de time de ejecución: cada function es un object y captura un cierre, es decir, aquellas variables a las que se accede en el cuerpo de la function. Las asignaciones de memory (tanto para objects funcionales como para classs) y las llamadas virtuales introducen gastos indirectos de time de ejecución.

Pero parece que en muchos casos este tipo de sobrecarga puede eliminarse al include las expresiones lambda.

Por lo que puedo decir que sí, alineará la function y eliminará cualquier sobrecarga que de otro modo se impondría.

Sin embargo, esto parece aplicarse solo a las funciones que declaras como en inline .

  • Prueba JUnit en Kotlin
  • Restricción del layout de la falla intermitente del layout
  • RxJava zipCon error IDE en Kotlin con Android Studio 3.0
  • reproducir cualquier video embedded en la vista web en Android con intención
  • ¿Por qué String dividir con una cadena de expresiones regulares en Kotlin no es lo mismo con Java?
  • Cómo exportar funciones de Kotlin a Javascript con el nombre correcto
  • Actualice el contenido de un fragment en SectionsPagerAdapter
  • Función genérica con matriz 2D genérica
  • Una buena forma de acceder a palabras mixtas de 8/16/32 bits
  • Android: Cómo hacer convertidores de tipo (para Habitación) generics para todos Lista de objects en Kotlin
  • Combinar arguments de constructor opcionales obligatorios y arbitrarios con Groovy