Создаются ли локальные переменные и функции в Котлине заново каждый раз, когда вызывается функция?

Рассмотрим этот код:

class Foo {
    fun bar() {
        val localVariable = 1

        fun localFunction() {
            // ...
        }

        // Rest of the code
    }
}

Каждый раз, когда я звоню bar(), будет ли localVariable «пересоздан» и localFuncion() «переопределен»? По сути, лучше ли с точки зрения производительности иметь их обоих в области класса, а не в локальной области, если я знаю, что буду вызывать bar() несколько раз?
Я предполагаю, что, поскольку localVariable является val (окончательным), возможно, его значение будет либо встроено, если это возможно, либо кэшировано между вызовами bar() компилятором. Это правда?

На какую платформу вы ориентируетесь? JVM, JS или Native?

Sweeper 29.04.2024 12:29

JVM для приложений Android

Anchith Acharya 29.04.2024 12:41

Этот вид оптимизации настолько микроскопичен, что если вы об этом беспокоитесь, этот модуль вашего кода должен быть выполнен в JNI. В подавляющем большинстве случаев вам следует отдавать приоритет ясности кода над подобными микрооптимизациями.

Tenfour04 29.04.2024 16:00

Другая причина не пытаться проводить микрооптимизацию заключается в том, что ваш код — это только отправная точка: оптимизатор JVM может полностью его преобразовать, и он, скорее всего, добьется большего успеха в коде, который ясен, прост и понятен.  Хорошо проектируйте, используйте правильные алгоритмы и понятный код и не беспокойтесь об оптимизации до тех пор, пока вы не сможете продемонстрировать проблему (и даже тогда не измерите эффект ваших изменений).

gidds 30.04.2024 11:31
За пределами сигналов Angular: Сигналы и пользовательские стратегии рендеринга
За пределами сигналов Angular: Сигналы и пользовательские стратегии рендеринга
TL;DR: Angular Signals может облегчить отслеживание всех выражений в представлении (Component или EmbeddedView) и планирование пользовательских...
Sniper-CSS, избегайте неиспользуемых стилей
Sniper-CSS, избегайте неиспользуемых стилей
Это краткое руководство, в котором я хочу поделиться тем, как я перешел от 212 кБ CSS к 32,1 кБ (сокращение кода на 84,91%), по-прежнему используя...
0
4
112
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В Kotlin/JVM локальные функции будут скомпилированы в методы включающего класса, как и обычные методы экземпляра. Локальные переменные, захватываемые локальной функцией, будут переданы в качестве параметров. Таким образом, в скомпилированном двоичном файле нет большой разницы между написанием локальной функции и написанием метода экземпляра.

Инициализаторы локальных переменных запускаются каждый раз, когда вы вызываете включающую функцию. В случае localVariable это всего лишь две инструкции байт-кода — помещение константы 1 (iconst) и сохранение ее в localVariable (istore). Я бы не беспокоился о производительности здесь.

Если инициализация переменной требует много времени, то вместо этого вы можете записать ее как свойство экземпляра, предполагая, что это не изменит правильность bar. Инициализаторы свойств экземпляра будут запускаться каждый раз, когда создается новый экземпляр этого класса.

Будет ли компилятор вставлять vals, это деталь реализации компилятора. Нет никаких гарантий.

> Если инициализатор переменной отнимает много времени, возможно, вы захотите вместо этого записать его как свойство экземпляра. Единственная проблема, которую я вижу в этом, заключается в том, что иногда просто нет смысла для localVariable быть частью класса. сам по себе, а не ограничиваться локальной областью действия bar(). Но я думаю, это нормально, поскольку это случается не так уж часто, и я был бы готов терпеть эту маленькую любимую недовольство из-за улучшения производительности, полученного за счет превращения ее в переменную экземпляра.

Anchith Acharya 29.04.2024 16:02

Другие вопросы по теме