Pull to refresh
75
-1
Alexey Andreev @konsoletyper

Пользователь

Send message

Компилятор Java написан, не поверите, на Java. JVM написана на C++, но там на C++ написан рантайм, интерпретатор и JIT. Внутри себя они, возможно, где-то и используют массивы C. При этом уже в Java массив не имеет ничего общего C++, не инстанциируется через него и вообще иначе реализован, иначе аллоцируется. При этом следующий уровень абстракции, ArrayList, написан на Java.

На Java и Kotlin. В частности, ArrayList для JVM BE просто алиасится в java.util.ArrayList, написанный на Java

Kotlin все равно реализован на сях (ИМХО)

Эээ, нет

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

Под постоянным, как я понял, имеется в виду O(1) (например, в отличие от связного списка с его O(n)). Это не отменяет наличия константы, которая так или иначе связана с особенностями оборудования. Иначе тогда и сортировку можно вместо O(N * log(N)) притянуть всякое . Кстати, кэш - не единственный источник тормозов. Может быть так же

  1. Страничная адресация. Кэш страниц в ЦП + всякие особенности управления страницами в ОС

  2. Банальное обновление памяти

Вот никогда не понимал этого. Я ещё понимаю, во всяких OCaml, где никаких циклов не заложено by design, там хвостовая рекурсия - это единственный способ писать оптимальный код. Но Kotlin - нормальный императивный язык, нет вообще ни одной причины тот код, который легко и читабельно представим циклами, переписывать в хвостовую рекурсию. Но вот взяли и потратили силы на то, чтобы это реализовать. Чтобы что? Поставить галочку напротив "ещё одна фича из функциональных языков"? Ради читабельности? Не думаю, что большинству разработчиков удобнее спарсить глазами того же Фибоначчи в "декларативном" стиле, чем через старый добрый цикл. Кроме того, часто такие элегантные математические определения из учебника не ложатся в хвостовую рекурсию и нужно их переписать, так что они уже не будут выглядеть такими же элегантными.

Вторая компания со схемы выше может в один прекрасный день заявить: «Мы
хотим поступать порядочно и оплачивать труд людей, работающих над
программами с открытым кодом». Но ээээ… куда именно им посылать деньги?
Понятия не имею

Не согласен с автором. По личному опыту народ не сильно торопится донатить. Вот я знаю, что моим проектом пользуется одна большая компания, которой какие-нибудь $50 в месяц вообще не проблема оформить. Я даже обращался к знакомым сотрудникам, говорили, что спросят у начальства. С закономерным итогом. А так, люди не стесняются приходить, спрашивать, что делать, если что-то у них не получается, оставлять issue, просить отревьюить их PR, объяснить, почему сложно реализовать ту или иную фичу - и такое ощущение, что и значок на github, и на сайте проекта, выпадает из их поля зрения. Чтобы набрать спонсоров, надо либо делать или что-то мегаполезное с огромной аудиторией, либо обладать не-инженерными навыками продвижения.

Ну а бывает, что WebAssembly медленнее. Я тут недавно баловался с бенчмаркингом своего JVM -> JS/WebAssembly транслятора и написал для него на Kotlin софтверный 3D. И вот почему-то WebAssembly вариант работает медленнее.

Думаю, там была проблема не техническая, а политическая. Авторы браузеров не хотели иметь какую-то стороннюю инородную штуковину, которая подключалась через небезопасный API. Авторы браузеров так же не хотели лицензировать Java у Sun/Oracle (чтобы включить эту инородную штуковину прямо в код бразура) и впадать в зависимость. WebAssembly - это что-то схожее, но изобретённое у них, так что нет, не повторит.

У кода на любом языке, скомпилированного в WASM всё-таки эффективность
(и в плане размера, и в плане производительности) будет гораздо лучше,
чем у того же кода, транспилированного в JS.

А вот и нет

Ещё причина в том, что порой хочется написать про то, что делаешь на работе, а из чисто внутреннего контекста это сложно выдрать. Вот например, делаю я сейчас UI-фреймворк для игрового движка. Игровой движок проприетарный, используется чисто внутри компании для разработки внутренних продуктов. И вот для меня персональная гордость - движок стилей а-ля CSS. Там целый ворох нетривиальных технических решений, чтобы это быстро работало на больших таблицах стилей (300+ селекторов) и на больших UI (10K+ view) и в том числе, инкрементальные апдейты - это когда вы поменяли класс где-то глубоко в иерархии view или что-то небольшое добавили в уже гигансткое дерево view, и стили пересчитались не за 100 мс, и даже не за 10 - счёт идёт на микросекунды. Ну и вот как всё это расписать для внешней публики? Для этого нужно вначале взять и написать такой же UI-фреймворк в опенсорсе, а зачем и кто за это будет за это платить? А выложить уже готовый движок в опенсорс мешает руководство.

Да, такие возможности есть, но это работает только в случае, если приложение написано целиком на Kotlin. Если же это Kotlin + Java, то спасает только native image или другие подобные AOT-компиляторы. Честно, я не в курсе, что сейчас творится на этом рынке, когда-то ещё были MOE, RoboVM и Avian, здравствуют ли они поныне - я не проверял.

Есть ещё один юзкейс для graal native image: компиляция приложений под iOS. Иногда в этом есть смысл, если хочется на Java/Kotlin ваять кроссплатформенно, но нативный look&feel вообще не нужен (например, игры).

Что касается неудобств с reflection, то тут есть одно решение: не использовать. Вы не поверите, на что способны annotation processor в умелых руках, дополненных compile time инструментацией байт-кода. Хотя полагаю, что, для spring boot это может быть невозможно.

С тестами нет вообще никаких проблем (проект в репозитории содержит несколько тестов). Наоборот, в виду специфики я для подобных байткодогенераторов стараюсь побольше тестов писать. А вот отладка - только логгированием.

Кстати, для junit 4 можно писать раннеры, которые тестовые классы загружают в кастомном лоадере, что может быть очень удобно при тестировании генераторов. Увы, в 5-м авторы перемудрили с системой расширений и такая возможность пропала.

Сколько там людей на планете понимает как c2 работает

Ну зачем же c2? Я про javac, kotlinc, scalac и иже с ними. c2 - это уже уровнем пониже и немного другие скилы.

Тут я пас. javac наше все. Код на сервере.

Так AOT-компиляторы обычно берут байт-код, там перед AOT-компилятором старый-добрый javac.

С чем угодно они уже довольно работают.

Вы про java.lang.reflect.Proxy? Не поддерживают.

Вот конкретно этот пример - не уверен, не пробовал. Если взять из моего примера генерацию байт-кода класса, сохранить его в виде класса с расширением class и прилинковать к проекту - класс загрузится. Какой бы ни был внутри android формат классов, SDK умеет переводить байт-код JVM в свой собственный формат. Не вижу причин, почему бы нельзя было в ClassLoader поддержать прозрачную трансляцию из байт-кода JVM в собственный формат - это должно быть тривиально. Боюсь только, что Android такой сгенерированный на лету байт-код будет интерпретировать или если сконвертирует в нативный код, то с минимальным числом оптимизаций.

Что касается моего личного опыта, то я использую на своём текущем проекте самописные генерялки байт-кода для нужд сериализации данных, RPC и привязки данных к OT. Но работают они в compile time.

Главное чтобы это на собеседованиях спрашивать не начали, блин.

Проекты проектам рознь. Где-то понимать, как генерируют байт-код JVM - это первейший необходимый навык. В компиляторных командах, например.

Прокси, лямбды и все такое что я перечислил

Прокси, как я уже написал, плохо работают с AOT-компиляторами и proguard/r8. Постоянно приходится думать, а не придётся ли мне после написания или рефакторинга очередной пачки кода завайтлистить ещё каких классов, чтобы приложение не упало. Можно всё то же самое сделать через кодогенерацию. Обычно всё же генерируют исходники через annotation processors, но бывают нюансы.

Ну и кстати, прокси работают только с интерфейсами, а не с абстрактными классами.

Если вам надо лезть в байт код, например для оптимизации, то пора переписывать код на плюсы

Это смотря какого рода оптимизации. Если есть алгоритм, который раз и навсегда написан, то да, это кейс. Если же пользователь что-то вводит и это что-то надо максимально быстро исполнить для разных входных данных (собственно, игрушечный проект в статье - намёк на такой кейс), то я лучше сгенерю байт-код Java, чем напишу на C++ генератор нативного кода. Пример: различные пользовательские скрипты. Да, в 90% случаев проще прикрутить что-то стандартное вроде JS, но бывает всякое. Ну например, представьте, что вы пишете Excel-подобную штуку и пользователь хочет (а он 100% хочет), чтобы формулы пересчитывались максимально быстро.

Плюс JNI имеет достаточно большие накладные расходы. И нативный код не инлайнится.

У всех свой продакшен. Мы вот используем и рады. Да и потом, если не все генерируют байт-код в продакшене, мало ли что. Где-то что-то не срослось и приходится смотреть глазами вывод `javap -c`. Или где-то заглючил спринг или хибернейт и сгенерил какую-нибудь обёртку, не проходящую валидацию. Так что понимать, как устроен байт-код - очень полезный навык, а для этого хорошо поупражняться таким способом.

Кстати, а можете привести конкретные доводы, почему именно "нет ни одного повода"?

А, увидел, что они добавили поддержку, но только экспериментальную и только для хрома под флагом

Поиск по словам j2cl дал только вот эту issue, которая ещё не закрыта. Можно ссылку на новость или на документацию по поддержке WebAssembly в j2cl?

Information

Rating
Does not participate
Location
München, Bayern, Германия
Date of birth
Registered
Activity

Specialization

Specialist
Senior
From 6,000 €
Java
Compilers
Kotlin
Gradle