Как стать автором
Обновить

Комментарии 13

но пока везде где это возможно нужно использовать этот модификатор (inline)

Вредный совет.
Inline стоит использовать так где он действительно нужен.

Обоснование моего вывода описано выше.
Обоснование того что это вредно привести можно?


Так же было бы очень интересно узнать о том, где inline нельзя использовать или хотя бы те, где его наличие и отсутствие хоть на что-то влияло бы.

Обоснование моего вывода описано выше.

Я так и не понял практического смысла. Да у вас jar будет на пару кб больше. И?


Обоснование того что это вредно привести можно?

Очень просто, если у вас размер метода такими инлайнами вырастет за определенный размер(емнип около 35 инструкций), к нему не будут применяться многие оптимизации JIT.


Но меня это мало интересует, меня больше интересует чистота кода, и inline который используется от балды есть плохо пахнущий код, имо.

Я так и не понял практического смысла. Да у вас jar будет на пару кб больше. И?

Практический смысл именно тот, чтобы не было лишнего, абсолютно бессмысленного кода.
К примеру, каждый раз, когда в программе используется конструкция:


fun Action( cb:()->Unit ) {}

fun statMethod() {}

fun Test() {
  Action( ::statMethod )  // эта конструкция
}

Будет сгенерирован очередной уникальный класс, который от прошлого использования такой конструкции будет иметь всего одно отличие: номер в имени.
Если Вас абсолютно не волнует какой код будет сгенерирован компилятором и как он будет работать, лишь бы программа выполнялась, то эту статью можно с чистой совестью забыть.
Меня лично такие вещи интересуют и "плохо пахнущим" кодом я как раз считаю такой, где разработчику абсолютно дофонаря какую именно конструкцию использовать.
Но это мои тараканы, я не навязываю :)


Да у вас jar будет на пару кб больше. И?

Насчет пары кб — это откуда взялось?
В тексте выше же есть цифры.
КАЖДОЕ использование такой конструкции добавит около полутора Кб.
Если их в коде используется сто, то будет + 1.5Мб...


Вообще, эта статья родилась как результат исследования, которым я занялся, когда с удивлением обнаружил что тест для моего DSL, не имея практически никакого кода с текстом на пру экранов, занимает в 4 раза больше, чем лежащая рядом софтина в размером исходников в пару сотен Кб.
Заинтересовался, выяснил отчего так происходит.
Решил поделиться.


Очень просто, если у вас размер метода такими инлайнами вырастет

Либо я чего-то в принципе не понимаю, либо Вы.
О размере какого метода идет речь?
Код, который генерируется в месте объявления автоматического класса, абсолютно никак не зависит от того в каком именно файле этот класс физически расположен.
Наличие inline влияет только на место расположения сгенерированного класса и не более того.

По первой части: если это действительно проблема, то нужно написать разработчикам в слаке, или еще лучше завести issue youtrack:
https://youtrack.jetbrains.com/issues/KT
http://kotlinslackin.herokuapp.com/


В противном случае вы только учитите плохому.


По второй части — 3 часа ночи, завтра на свежую голову перечитаю.

если это действительно проблема

С точки зрения меня (если поставить себя на место разработчиков) довольно сложно называть это проблемой, и тем более проблемой именно Kotlin.


Разработчики сохраняют классы в отдельные файлы а, при использовании inline, пользуются возможностью появившейся в Java, которая позволяет разместить в одном файле несколько классов.
То, что в первом случае файлы обладают гигантским оверхедом к коду, в сравнении с размещением их в уже существующем файле, ставить в вину нужно скорее тем, кто придумал формат class-файлов, а не разработчикам Kotlin.


На мой взгляд описанное в статье — это скорее "фича", которую имеет смысл знать и использовать, а не какая-то проблема.


Проблемой можно назвать отсутствие какой-нибудь оптимизации, но, я уверен, это известно и без меня и, если язык будет развиваться, она появится.


ПС: Повторно прошу обосновать утверждение о вреде, которому я "учу".

Разработчики сохраняют классы в отдельные файлы а, при использовании inline, пользуются возможностью появившейся в Java, которая позволяет разместить в одном файле несколько классов.


А это что за возможность такая?

Я имел в виду то, что в Java с какой-то версии (1.2 или 1.4 — не разбирался точно) появилась возможность в одном файле класса описывать сколько угодно классов верхнего уровня.
Но в первоначальной статье у меня была ошибка, поэтому в текущем варианте это уже не важно.

Я с деталями реализации Kotlin не знаком, а почему они не пошли по пути лямбд Java, где класс-реализация генерируется автоматически в райнтайме через LambdaMetafactory#metafactory?

Я, в свою очередь, не знаком с деталями Java, но то что я вижу сейчас в сгенерированном из Java коде производит абсолютно такие же действия, как и компилятор Kоtlin: создается новый класс для каждого места использования лямбды и ему в конструкторе передаются захваченные переменные.
Насколько я понял "LambdaMetafactory" — это возможность для пользователя. Компилятор Java ее не использует.


Сейчас реализация Kotlin описана более подробно в текущем варианте статьи выше.

Нет, Java (компилятор) не создает новый класс для каждого места использования лямбды (если речь о 1.8 -> 1.8), а использует LambdaMetafactory/invokedynamic. Это легко проверяется компиляцией вот такого кода:
import java.util.function.Supplier;

public class Test {

    public static void main(String... args) {
        String hello = "hello";
        print(() -> hello + ", world!");
    }

    public static <T> void print(Supplier<T> s) {
        System.out.println(s.get());
    }
}


И последующей декомпиляцией через «javap -verbose -p Test»

P.S. В рантайме да, создается класс, насколько я помню.

В любом случае создается класс.
Какая разница как это делается, компилятором при сборке программы или генерацией его кода на лету через миллион библиотечных прослоек?
Лично мне, после беглого разглядывания java\lang\invoke*.java, гораздо более симпатичен подход, который используется именно в Kotlin.


ПС: Я не думаю что в Kotlin изменят способ обработки кода т.к. одной из задач этого компилятора собираться под мобильные платформы а, насколько я знаю, даже на Android, существенные проблемы с генерацией кода на лету.
Но я не специалист, поэтому в обсуждение ввязываться не буду :)

Потому что до версии 1.1 Котлин таргетится на байткод 1.6. После релиза 1.1 (который должен быть довольно скоро) будет возможность указывать таргет 1.8, там будет именно так.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации