LINUX.ORG.RU

Что сейчас можно на JVM

 , , ,


0

2

Комрады, вопрос в теме, что сейчас передовое для использования в разработке на JVM? Какие языки сейчас есть и какие популярны для новых проектов. Есть проект, который пилится на Java 16, интересно что сейчас ещё на платформе востребовано/используемо кроме Java и Kotlin. Заранее всем спасибо!

Ответ на: комментарий от iZEN

В каком месте отказ от исключений запрещает приложению бороться за свою живучесть?

Ответ во второй части моего предложения.

а программиста — на выполнение дополнительных действий по повышению надёжности разрабатываемого ПО

Нет там ответа и смысл тот же, что и у первой части — потому я ее обреза. И даже пояснил, откуда берется это твое предубеждение. Более того, исключения приводят к появлению ненадежного ПО, которое при нештатной ситуации сходит с ума, потому что обработка исключений не была оттестирована должным образом.

byko3y ★★★★
()
Ответ на: комментарий от Legioner

Для меня лямбды это синтаксический сахар над анонимными классами, которые в Java были почти всегда

Я не удивлюсь, если ты привык писать анонимные классы и не видишь в этом ничего неудобного. А проблема здесь в том, что классы — это тупо лишнее звено, они засоряют код. Да, IDE помогает меньше мучаться, но в итоге IDE устраняет кучу реальных недостатков языка, которые никуда сами по себе не исчезли — ты просто заменил язык Java на язык Eclipse/NetBeans/IntelliJ Idea, но на жаве ты не пишешь, потому что иначе прочувствовал бы всю боль и страдание.

вывод типов это вообще спорная фича, в какой-то мере противоречащая основам Java (например var l = new ArrayList() даёт переменную типа ArrayList, хотя любой Java-ист написал бы List l = new ArrayList<>)

Это пример убогости конкретного жавового вывода типов, которая, например, не свойственна расту.

То-то каждый суслик нынче на электроне клепает аппы и пофиг ему на десктопное окружение и драг-н-дропы

Это модно, но это не значит, что у них получается что-то юзабельное. Получается лютый кал, и многие проекты таки предпочитают писать нативщину. Да тот же Facebook.

Electron это нативное приложение и оно имеет доступ к любым API операционной системы, в крайнем случае надо FFI дописать в несколько строчек

Эти «несколько строчек» нужно написать, под каждую систему, с учетом всех поддерживаемых версий. Хром предоставляет интерфейсы, которые кроссплатформенны. Если как ты рассуждать, то можно было бы и на Qt писать — а чо, интерфейсы GUI те же ведь на всех платформах, а специальные под каждую платформу по необходимости допишем.

У JVM есть определённые проблемы, мешающие использовать её в GUI. В первую очередь это странная система управления памятью, когда нужно настраивать Xmx и она освободившуюся память системе отдавать не хочет... Насколько я понимаю, Electron этих проблем лишён

Сейчас пользователи приложений на электроне улыбнулись. Потому что если электрон и жрет меньше оперативы, то не сильно меньше — это по прежнему жоркая и тормознутая штука.

Справедливости ради, успехом современная версия VS Code не в последнюю очередь обязана WebAssembly — турбореактивный парсинг сорцов сделан именно нем.

Он в любом случае медленней JVM

В 2 раза медленнее родных машинных кодов, по состоянию на 2019 год. По этой причине какие-то очень хорошо заоптимизированные куски в JVM с локализированными и скаляризованными данными могут выполняться быстрее. Однако, у WAsm нет сборки мусора, и потому при работе в куче картина поменяется в его сторону. Особенно если говорить про какую-нибудь реализацию парсинга на самой жаве, которая будет генерировать огромное число мелких объектов в куче, а потом неспешно их перебирать.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Сейчас пользователи приложений на электроне улыбнулись. Потому что если электрон и жрет меньше оперативы, то не сильно меньше — это по прежнему жоркая и тормознутая штука.

Проблема не столько в том, сколько памяти жрёт приложение в типовом использовании, а в том, сколько памяти жрёт приложение в пике. К примеру взять дискорд. Я могу сидеть на одном сервере, а могу на ста серверах. Понятно, что в последнем случае памяти надо жрать больше. При этом если я использую JVM, я либо ставлю Mx на последний случай гигов на 5, но тогда первый случай тоже съест эти гиги. Либо я ставлю на первый случай на 500 мегабайтов, но тогда последний случай тупо упадет по OOM, хотя у человека памяти на машине хватает. Ну либо просить пользователя редактировать стартовые скрипты, что, очевидно, подойдёт разве что для программистских инструментов (как это делает Idea).

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

Скорей всего это не проблема. Все эти мелкие объекты лежат в молодом поколении и собираются очень быстро. В JVM не куча, а несколько куч. Я не спорю, что это не слишком хорошо, но на практике это работает достаточно быстро и обычно не является главным источником тормозов, если код написан более-менее аккуратно.

Тот же javac написан на Java и компилирует эту самую Java очень быстро (в отличие от всяких Gradle-ов, которые его вызывают, но при этом непонятно почему тормозят как чёрт знает что, хотя вроде ничего толком и не делают).

Не, я не спорю, если взять кусок кода, аккуратно написать его на C++/Rust и скомпилировать под Wasm, вероятно он может опередить аналогичный Java-код. Но тут есть мнение, что всё же Java это язык более высокого уровня. А если к такому сравнению подходить, то с тем же успехом можно этот же код написать на C++/Rust и скомпилировать под конечную архитектуру и потом вызывать его из Java аналогично тому, как это делает JavaScript. Это более честное сравнение. А вот когда в WASM добавят GC и какой-нибудь похожий на Java язык реализуют (а может и саму Java, чем чёрт не шутит), тогда и можно будет сравнивать.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 4)
Ответ на: комментарий от Legioner

Я могу сидеть на одном сервере, а могу на ста серверах. Понятно, что в последнем случае памяти надо жрать больше. При этом если я использую JVM, я либо ставлю Mx на последний случай гигов на 5, но тогда первый случай тоже съест эти гиги. Либо я ставлю на первый случай на 500 мегабайтов, но тогда последний случай тупо упадет по OOM, хотя у человека памяти на машине хватает

Проблема очень простая — сборка мусора в JVM сильно ухудшает производительность. Например, в новых реализациях вводят сжатие кучи при простое процесса. Под нагрузкой же JVM мухлюет со сборкой, выполняя ее не до конца. Ух, мне сложно представить, сколько программистов в Sun поседело, пытаясь заставить жаву бегать быстро.

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

Все эти мелкие объекты лежат в молодом поколении и собираются очень быстро. В JVM не куча, а несколько куч. Я не спорю, что это не слишком хорошо, но на практике это работает достаточно быстро и обычно не является главным источником тормозов, если код написан более-менее аккуратно

Ну распарсенную структуру же нужно в куче хранить. Да, там будут еще и локальыне объекты, которые пойдут в стэк и не засорят кучу, но и без них весело.

Тот же javac написан на Java и компилирует эту самую Java очень быстро

Порядка тысяч строк в секунду. Написанный на крестах и заброшенный Jikes выдает 20k+ строк в секунду. Примерно похожую скорость имеют компиляторы Си. Компилятор паскаля, написанный специально с расчетом на простоту парсинга и компиляции, имеет скорость 100-200к строк в секунду. Естественно, без обобщений и без сложных зависимостей. Я видел проект на паскале, который компилировал единицы тысяч строк в секунду при миллионах строк всего в проекте.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Порядка тысяч строк в секунду.

Это скорость внутреннего интерпретатора (среды программирования).

javac компилирует исходники гораздо быстрее — скорость сравнима с компилятором Delphi. И уж конечно быстрее, чем компиляторы на C++, на сравнимых объёмах исходных текстов.

iZEN ★★★★★
()
Последнее исправление: iZEN (всего исправлений: 1)
Ответ на: комментарий от byko3y

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

Для молодого поколения используется копирующий GC, и не важно сколько короткоживущих объектов, их может быть больше миллиарда, на скорость сборки это никак не влияет, т. к. неиспользуемые объекты не перебираются.

ma1uta ★★★
()
Ответ на: комментарий от iZEN

javac компилирует исходники гораздо быстрее — скорость сравнима с компилятором Delphi. И уж конечно быстрее, чем компиляторы на C++, на сравнимых объёмах исходных текстов

Вполне возможно, что так и есть, но откуда инфа? Мне не удалось найти подтверждение слов легионера о том, что javac быстро работает. А тысячи строк с секунду умеет транслировать даже нода.

И уж конечно быстрее, чем компиляторы на C++, на сравнимых объёмах исходных текстов

Справедливости ради — компилятор жавы при интенсивном использовании перегрузок функций начинает буксовать, как буксует паскалевый на сложных зависимостях и шаблонах, как буксует C++ на сложных шаблонах. Тем не менее, в среднем по палате парсинг жавы представляет собой весьма простую задачу.

byko3y ★★★★
()
Ответ на: комментарий от ma1uta

Для молодого поколения используется копирующий GC, и не важно сколько короткоживущих объектов, их может быть больше миллиарда, на скорость сборки это никак не влияет, т. к. неиспользуемые объекты не перебираются

Но оказывают влияние объекты, на которые сошлются долгоживущие объекты, даже если это будет кратковременная ссылка. Чисто локальные объект в JVM научились оптимизировать, тут вопросов нет, будь то помещение в стэк или в молодую кучу.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Вполне возможно, что так и есть, но откуда инфа?

Компилировал OpenOffice и Eclipse JDT — полтора часа компилирует C++ и пятнадцать минут компилирует javac, соответственно.

iZEN ★★★★★
()
Ответ на: комментарий от Legioner

например var l = new ArrayList() даёт переменную типа ArrayList

Пардон, а с какой стати оно должно выводиться в List? А если ArrayList еще какие-то интерфейсы реализует? Collection, Iterable? На каком основании должно приниматься решение? По факту что справа, то слева и получаешь - просто и понятно.

И в конце концов, в чем реальная практическая проблема (без «принципов java»), что локальная переменная имеет тип конкретной реализации?

Midael ★★★★★
()
Последнее исправление: Midael (всего исправлений: 4)
Ответ на: комментарий от iZEN

На git://git.eclipse.org/gitroot/jdt/eclipse.jdt.core.git по моим прикидкам где-то 600 тыс строк (30 Мб сорцов). Даже если предположить, что какие-то там модули еще столько же весят, и даже если считать с тестами, которые еще на лям строк — получится такая себе скорость, весьма далекая от сотен тысяч строк в секунду.

byko3y ★★★★
()
Ответ на: комментарий от Midael

Пардон, а с какой стати оно должно выводиться в List? А если ArrayList еще какие-то интерфейсы реализует? На каком основании должно приниматься решение? Что справа, то слева и получаешь

На основании использования переменной, по минимальным ограничениям, с которыми код заработает.

И в конце концов, в чем реальная практическая проблема (без «принципов java»), что локальная переменная имеет тип конкретной реализации

В том, что код может не скомпилироваться, если я захочу присвоить этой переменной другое значение.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

На git://git.eclipse.org/gitroot/jdt/eclipse.jdt.core.git по моим прикидкам где-то 600 тыс строк (30 Мб сорцов).

Я всё собирал на FreeBSD из портов editors/openoffice и java/eclipse, соответственно. Строились из соответствующих портов и устанавливались в систему сами пакеты, зависимости были разрешены ДО.

При этом OpenOffice для своей компиляции нуждался в памяти 11-12 ГБ, а Eclipse IDE собиралось на менее чем 4 ГБ.

получится такая себе скорость, весьма далекая от сотен тысяч строк в секунду.

Для Eclipse IDE нужно ещё запаковать откомпилированные готовые классы в сотни jar-файлов. Так что сравнивались не только компиляция, но и сборка.

iZEN ★★★★★
()
Последнее исправление: iZEN (всего исправлений: 1)
Ответ на: комментарий от byko3y

Живое. Автоматизация для всяких джир и дженкинсов идет отлично.

PunkoIvan ★★★★
()
Ответ на: комментарий от Midael

Пардон, а с какой стати оно должно выводиться в List? И в конце концов, в чем реальная практическая проблема (без «принципов java»), что локальная переменная имеет тип конкретной реализации?

Потому, что это правило хорошего тона в Java. Чтобы случайно не использовать методы из ArrayList и иметь возможность заменить реализацию на любую другую.

А если ArrayList еще какие-то интерфейсы реализует? Collection, Iterable? На каком основании должно приниматься решение?

Я не предлагаю хорошее решение. Я критикую текущее. Если предлагать своё решение, нужно дорабатывать синтаксис, вроде

class ArrayList<T> implements List<T> as default var type, ...

По факту что справа, то слева и получаешь - просто и понятно.

Просто и понятно, но имеет свои минусы, которые я описал.

Legioner ★★★★★
()
Ответ на: комментарий от Midael

Ключевое слово var

И что, есть языки которые тип выводят именно по паттерну потребления?

Начиная с Java 10 в язык было добавлено ключевое слово var, которое также позволяет определять переменную:

var x = 10;
System.out.println(x); 	// печатает 10

Слово var ставится вместо типа данных, а сам тип переменной выводится из того значения, которое ей присваивается. Например, переменной x присваивается число 10, значит, переменная будет представлять тип int.

Но если переменная объявляется с помощью var, то мы обязательно должны инициализировать ее, то есть предоставить ей начальное значение, иначе мы получим ошибку, как, например, в следующем случае:

var x;		// ! Ошибка, переменная не инициализирована
x = 10;

Источник

iZEN ★★★★★
()
Ответ на: комментарий от Legioner
import java.util.Collection;
import java.util.ArrayList;

public class Test {

    static void printCollection(Collection<?> c) {
        c.forEach(o -> {
            System.out.print(o);
        });
    }

    public static void main(String[] args) {
        Collection<String> cs = new ArrayList<>();
        cs.add("Привет");
        cs.add(",");
        cs.add(" ");
        cs.add("мир");
        cs.add("!");
        printCollection(cs);
    }

}
iZEN ★★★★★
()
Ответ на: комментарий от Midael

И что, есть языки которые тип выводят именно по паттерну потребления?

Все языки (обычно это функциональщина) с хорошим выводом типов это умеют. Например OCaml, из него и в rust перекочевало, но только для локальных контекстов.

anonymous
()
Ответ на: комментарий от iZEN

Для Eclipse IDE нужно ещё запаковать откомпилированные готовые классы в сотни jar-файлов. Так что сравнивались не только компиляция, но и сборка.

Для С++ нужна кроме компиляции еще и линковка, она думаю сейчас уже посложнее чем паковать в zip.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.