¿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 .

  • Kotlin - Transforma el valor en la initialization
  • Crear map de lists de Spring config en Kotlin
  • MPAndroidChart datos en vivo no visibles sin límites iniciales
  • Kotlin Kapt: java.lang.IllegalStateException: endPosTable ya está configurado
  • Kotlin en xml onClick no funciona
  • Quiero poblar el adaptador de arrays de cada vista en el layout de un solo cuadro
  • Cómo extraer el map de la colección de objects, con la key como uno de los objects del mismo campo y valorar los objects reales
  • ¿Cómo uso AnkoComponent dentro de FirebaseRecyclerAdapter?
  • No se pueden encontrar las classs de Kotlin al comstackr IntelliJBehave
  • Kotlin: No se pueden aplicar dos condicionales a la vez. Verificar con el estilo de function de "cuerpo de retorno".
  • utilizando compile "org.jetbrains.kotlin: kotlin-stdlib-jre7: $ kotlin_version" give Error