Рассмотрим этот код:
class Foo {
fun bar() {
val localVariable = 1
fun localFunction() {
// ...
}
// Rest of the code
}
}
Каждый раз, когда я звоню bar(), будет ли localVariable «пересоздан» и localFuncion() «переопределен»? По сути, лучше ли с точки зрения производительности иметь их обоих в области класса, а не в локальной области, если я знаю, что буду вызывать bar() несколько раз?
Я предполагаю, что, поскольку localVariable является val (окончательным), возможно, его значение будет либо встроено, если это возможно, либо кэшировано между вызовами bar() компилятором. Это правда?
JVM для приложений Android
Этот вид оптимизации настолько микроскопичен, что если вы об этом беспокоитесь, этот модуль вашего кода должен быть выполнен в JNI. В подавляющем большинстве случаев вам следует отдавать приоритет ясности кода над подобными микрооптимизациями.
Другая причина не пытаться проводить микрооптимизацию заключается в том, что ваш код — это только отправная точка: оптимизатор JVM может полностью его преобразовать, и он, скорее всего, добьется большего успеха в коде, который ясен, прост и понятен. Хорошо проектируйте, используйте правильные алгоритмы и понятный код и не беспокойтесь об оптимизации до тех пор, пока вы не сможете продемонстрировать проблему (и даже тогда не измерите эффект ваших изменений).


В Kotlin/JVM локальные функции будут скомпилированы в методы включающего класса, как и обычные методы экземпляра. Локальные переменные, захватываемые локальной функцией, будут переданы в качестве параметров. Таким образом, в скомпилированном двоичном файле нет большой разницы между написанием локальной функции и написанием метода экземпляра.
Инициализаторы локальных переменных запускаются каждый раз, когда вы вызываете включающую функцию. В случае localVariable это всего лишь две инструкции байт-кода — помещение константы 1 (iconst) и сохранение ее в localVariable (istore). Я бы не беспокоился о производительности здесь.
Если инициализация переменной требует много времени, то вместо этого вы можете записать ее как свойство экземпляра, предполагая, что это не изменит правильность bar. Инициализаторы свойств экземпляра будут запускаться каждый раз, когда создается новый экземпляр этого класса.
Будет ли компилятор вставлять vals, это деталь реализации компилятора. Нет никаких гарантий.
> Если инициализатор переменной отнимает много времени, возможно, вы захотите вместо этого записать его как свойство экземпляра. Единственная проблема, которую я вижу в этом, заключается в том, что иногда просто нет смысла для localVariable быть частью класса. сам по себе, а не ограничиваться локальной областью действия bar(). Но я думаю, это нормально, поскольку это случается не так уж часто, и я был бы готов терпеть эту маленькую любимую недовольство из-за улучшения производительности, полученного за счет превращения ее в переменную экземпляра.
На какую платформу вы ориентируетесь? JVM, JS или Native?