LINUX.ORG.RU

Почему ЯП медленые?

 ,


0

3

Почему говорят что одни языки программирования медленые, а другие быстрые? Ведь это зависит от реализации компилятора или интерпретатора. А сам ЯП по сути синтаксис.

★★

Последнее исправление: tyamur (всего исправлений: 1)

Практика — критерий истины

anonymous
()

потому что на получение одного результата уходит разное количество машинного кода?

targitaj ★★★★★
()

Ведь это зависит от реализации компилятора или интерпретатора

Да, но в самом языке могут быть фичи, которые невозможно реализовать так, чтобы они были быстрые.

no-such-file ★★★★★
()

Ну так говорят про ЯП же не как про синтаксис а про весь рантайм.

micronekodesu ★★★
()

cам ЯП по сути синтаксис

Нет, конечно. Язык - это по сути семантика.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)

Ну вот например виртуальная машина jvm. Например написал ты на java код и скомпилировал для jvm. Для сравнения также написал код на си и скомпилировал. Теперь сравниваем.

Дизассемблируешь код сначала на си, смотришь ассемблерные команды, видишь, ага, чтобы вывести строку, нужно заполнить регистры данными и выполнить call. Смотришь скомпилированный код java, в дизассемблере видишь как работает виртуальная машина, то есть сначала надо разобраться в работе виртуальной машины. Насчет работы виртуальной машины, это я в книге какой то читал. Но не помню, дизассемблировал хоть раз код на java. Может как нибудь сравню. Уже сравнил, но только hexdump, получилось что сишный файл во много раз больше занимает места. Но сишный файл будет выполнять интерпретатор ld-linux а java класс будет выполнять java.

u0atgKIRznY5
()

А сам ЯП по сути синтаксис.

Правильно. Медленным или быстрым, как правило, являются не сами ЯП, а продукт работы компилятора/интерпретатора. Исторически так сложилось, что для одних ЯП по умолчанию предполагается компиляция в нативный код (сишка), для других в байткод (Java), третьи вообще интерпретируются (питон).

Хотя всё это носит относительный характер. И для питона есть компиляторы. И Java вроде как можно компилировать в нативный код - но я понятия не имею, сделал ли хоть кто-нибудь законченный продукт на компиляции Java в натив (cast stevejobs, Bioreactor - может, они расскажут). Java это ведь не только язык, но и весьма богатые стандартные библиотеки...

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

Так это две разновидности. Тогда можно написать интепретатор для си, а java компилировать в нейтив. И сказать си медленый. (условно)

tyamur ★★
() автор топика

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

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

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

Компилятор как раз знает. Если это JIT-компилятор.

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

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

Без понятия. Наверное, поэтому:

«Numba works by generating optimized machine code using the LLVM compiler infrastructure at import time, runtime, or statically»

Еще, наверное, потому, что LLVM довольно хреновый JIT. Вот PyPy аннотации не нужны.

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

Вот PyPy аннотации не нужны.

Нумбе тоже не нужны, но без них он делает медленный код. Может ли pypy генерировать код такой же быстрый, как C или фортран? Или хотя бы сравнимый по быстроте?

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

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

Т.е. говоря о скорости ЯП мы говорим о средней скорости популярных трансляторов.

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

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

u0atgKIRznY5
()
Ответ на: комментарий от hobbit

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

это называется JIT, и есть в дефолтной джаве. Наверное, самый лучший JIT в мире (лучше, чем в V8, например)

есть продукт Excelsior Jet, который использует гибридный подход с AOT, и может компилировать в как-будто-бы-exe.

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

Может ли pypy генерировать код такой же быстрый, как C или фортран? Или хотя бы сравнимый по быстроте?

Теоретически - да, на практике - не пользуюсь Python для вычислений. И просто для протокола: я отвечал на комментарий «компилятор динамического языка не знает, как сделать код быстрым». Он знает, техника известна: https://en.wikipedia.org/wiki/Inline_caching

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

Смотришь скомпилированный код java, в дизассемблере

ты не тот код смотришь.

То что у тебя в class-файле - это промежуточное представление, оно не будет выполняться на самом деле. Компиляция происходит только при _запуске_ приложения.

Смотреть настоящий скомпилированный машинный код, нужно выставить параметр "-XX:CompileThreshold=1" (это не рационально с точки зрения производительности, но тебе для отладки поможет), и потом собственно включить просмотр дизассемблера по конркетному классу и методу (ты же не хочешь видеть бесконечный ассемблерный листинг?) с помощью "-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod".

Чтобы это вообще заработало нужно настроить hsdis, вот тут есть инструкция для Windows, для Linux сам разберёшься.

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

однако это один фиг дополнительная функция проверки переменных перед непосредственной функцией над этими переменными.

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

однако это один фиг дополнительная функция проверки переменных

Это дополнительные инструкции проверки. Если ты хочешь сказать, что код от статически типизированного языка всегда будет быстрее - это не так.

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

имхо ручное указание хинтов действительно делает быстрей

грубо говоря, вот берет рантайм у тебя код и отправляет на выполнение. Откуда этот код взялся? ХЗ. Соответственно, если в параметры что-то придёт не «того типа», то всё сломается.

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

у нас в Graal/Truffle (экспериментальная JavaVM для запуска динамических языков как JavaScript), есть для этого специальные хаки. Обычно если метод запускается с каким-то типом, он запускается с ним всегда, и поэтому в профиле методов динамически можно проставить хинты, и оптимизировать до машинного кода. Предположение, на основе которого делается оптимизация, сохраняется в профиль метода. Если предположение нарушается, происходит деоптимизация до интерпретатора и собирается новая ветка машкода (старая или выбрасывается, или сохраняется, если в кэшах есть место)

Я по этому поводу вот такую статейку переводил: https://habrahabr.ru/post/329120/ (но надо понимать, что это просто курсач авторов алгоритма, в реальности там сложней)

ТАК ВОТ. В оригинально Java всего этого делать не нужно. Байткод (который пришёл неизвестно откуда) вначале верифицируется с помощью «верификатора байткода» относительно Java Virtual Machine Specification, глава 5. Там внутри используется хитрая математика над решётками и полурешётками, из которой следует, что если байткод полностью верифицирован (сходится), то по какому бы пути ни шел дальнейший разбор, он будет корректный по типам. И дальше ВСЕ ПРОВЕРКИ ВЫБРАСЫВАЮТСЯ.

Про верификацию вот тут есть хороший доклад одного из основателей Excelsior JET: https://www.youtube.com/watch?time_continue=3021&v=m16AIz1fIFI

Насколько там буст перфоманса - посчитать, к сожалению, нельзя - нечего не с чем сравнивать. Но есть забавный факт, что JavaScript, реализованный в рамках эксперимента по контекстно-зависимому инлайнингу трейсов, ТУПО НА ИНТЕРПРЕТАТОРЕ JVM (без JIT) выдал перфоманс, сравнимый с V8 в дефолтной конфигурации (т.е. и с дижтом, и со всем другим обвесом).

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

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

на компиляции Java в натив

Вы абсолютно правы.

https://habrahabr.ru/post/305894/

https://www.ibm.com/developerworks/ru/library/j-jtp12214/index.html

----

Вопрос в заголовке некорректен - речь идет о VM (например, JVM), а язык программирования может быть не обязательно Java -

https://ru.wikipedia.org/wiki/Список_языков_JVM

Bioreactor ★★★★★
()

Потому же, почему двуногие принципиально медленнее четвероногих. Последние лучше приспособлены для быстрого перемещения. Так и с ЯП, статически типизированные намного лучше «бегают», чем динамически типизированные.

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

Исторически так сложилось, что для одних ЯП по умолчанию предполагается компиляция в нативный код (сишка), для других в байткод (Java), третьи вообще интерпретируются (питон).

третьи вообще интерпретируются (питон)

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

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

двуногие принципиально медленнее четвероногих. Последние лучше приспособлены для быстрого перемещения.

Вот сейчас страусам было обидно.

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

А еще кому? Никому? Значит, страусы исключение, подтверждающее правило. Тем более они птицы, они вообще под метафору не попадают, генетическая аномалия.

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

Значит, страусы исключение, подтверждающее правило.

Еще человек бегает быстрее крокодила. Что намекает - не всё так просто со статическими и динамическими типами.

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

в гугл вбил «Java how to view JIT-compiled code»

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

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

Питон коренным образом отличается от джавы тем, что дефолтный питон (cpython) дефолтной версии (3.6.4) не содержит JIT, и скорей всего никогда не будет :) У них там без джита проблем достаточно - как там в 2017 можно [почитать здесь](http://faster-cpython.readthedocs.io/notes_2017.html). Из-за которых время от времени у людей сносит башню, и они тоже начинают писать инлайнинг трейсов, [и вот это всё](http://hotpy.org).

но есть pypy. Но с ним есть проблемы, ибо сишные экстеншены там поддерживаются хуже , чем в CPython - а кто без них кодит на питоне? (некоторые просто не работают).Pypy это JIT, а те хитрые опитмизиации которые впиливаются в CPython обходят его стороной - в одном улучшаем, в другом - теряем. Возможно всё потому, что pypy - не мейнстрим, и например, поддержку python3 им пришлось [краудфандить два года](https://pypy.org/py3donate.html). Когда какой-нибудь Microsoft потдхватит pypy, всё изменится.

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

А так ты получается ничего не знаешь, а все твое общение сводиться к тому, что прочитать чье то сообщение, посмотреть в google ответ и написать его?

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

Я джава-евангелист, и моя задача - помогать людям разбираться в Java. Для этого я подписан на тэг «java» на ЛОРе, и стараюсь отвечать на все осмысленные вопросы, на которые смогу найти ответ. Источники информации могут быть разные, в зависимости от задачи. Смотреть флаги лучше всего в гугле (или в исходнике, если ты понимаешь его).

Имхо, человек может придумать очень мало вещей сам по себе. Вся информация берётся из интернета или ближайшего окружения, а потом творчески переосмысливается (с небольшим добавлением от себя иногда). В твоей терминологии, я действительно «сам» ничего не знаю. А если что-то и узнаю, то сразу пишу на Хабр, и дальше отвечаю людям ссылкой на статью.

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

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 2)

Говорят руби медленный как раз из-за языка, типа дерево сложное получается + ООП.
Мопед не мой.

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

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

Virtuos86 ★★★★★
()

Всё зависит от абстракций. Чем более высокие и удобные абстракции используются, тем больше тормоза, как правило.

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

джава - это не интерпретатор байткода. Ну то есть, интерпретатор байткода в ней есть, но он - не главное. Сразу же как становится понятно, какая часть программы действительно нужна для выполнения, начинает выполняться _нативный_ код. Ближайший родственник и конкурент для Java - это C++. Java в реальности - это нативный машкод. Если бы не этот факт, Java тормозила бы как интерпретируемые языки типа Питона. Java юзают за огромную скорость выполнения и умение ворочать сотнями гигабайт RAM без необходимости в ручном управлении памятью - если бы она тормозила, место было бы ей только в мусорке. Это невероятно важная часть истории - самая важная. Вокруг JIT крутится всё: дизайн языка, компилятора, рантайма, библиотек, итп.

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

сейчас идёт борьба на несколько фронтов, в т.ч. за компактность и аппаратное ускорение. Появляется нечто, аналогичное структурам в C++. Со стороны JIT-комплиятора отчаянно бьются за автоматическую векторизацию на SSE/AVX/AVX-512/etc, а когда она не справляется - делают специальные библиотеки, позволяющие вручную расставить хинты (хороший доклад).

Насколько понимаю, в рамках этого проекта появится возможность сохранять кусок нативного кода (или x86-ассемблера) прямо в переменную особого типа, и запускать когда надо - получится что-то типа моей мечты о «джаве с ассемблерными вставками», но без компиляторных интринсиков, а автоматически

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

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

Вообще-то в теории jit компилятор может выдавать более производительный код, за счёт оптимизаций по информации которая доступна только в рантайме.

no-such-file ★★★★★
()
Ответ на: комментарий от stevejobs

Я джава-евангелист

Java в реальности - это нативный машкод

В реальности - ты обычный рыночный зазывала. Врать - часть твоей работы.

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

Мне одному кажется, что ява скатывается в отвратительное СГ? Код на ява 9 уже выглядит как perl. Скоро до уровня rust дойдут и можно будет менять профессию.

Deleted
()
Ответ на: комментарий от stevejobs

джава - это не интерпретатор байткода

Хороший ты евангелист, но я тебе не верю.

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

сейчас идёт борьба

с тем фактом, что Джава ничем не отличается от питонорубей, т.е. интерпретаторов байткода. Борьба с генетическими недостатками. И она хоть сколько-то успешна из-за бабок корпораций, а не потому что джава это C++.

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

Мне одному кажется, что ява скатывается в отвратительное СГ? Код на ява 9 уже выглядит как perl.

Из платформы с динамической подгрузкой классов во время выполнения Java в 9-й версии превратилась в монстрика со статическим разрешением зависимостей (модули). Динамические модульные системы на основе OSGi в Java 9 ломаются из-за разрешения зависимостей на этапе запуска!! С одной стороны это дисциплинирует программирование на Java и даёт по рукам, кто хакерит, а с другой стороны - язык теряет те свойства, которые в него были заложены изначально, и обрастает костылями для описания модулей и связей между ними.

Минусы Java как языка:

  • сопутствующие XML-конфигурации для JavaEE (преодолён аннотациями)
  • runtime-аннотации, замусоривающие код
  • плохо понимаемый контейнерный DI (вынуждающий применять runtime-аннотации)
iZEN ★★★★★
()
Последнее исправление: iZEN (всего исправлений: 2)

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

Запусти Turbo Pascal 7.0 и Turbo C++ 3.1. В каждой набери программку на своём языке по типу «угадай число». Откомпилируй. Вот где почувствуешь, какой язык медленный, а какой быстрый.

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

Динамические модульные системы на основе OSGi в Java 9 ломаются

...из-за того, что OSGi - говно.

про это даже отдельный доклад есть

теперь эти продукты придётся переписывать, а Рейнхольт между прочим десятками лет об этой проблеме намякивал

язык теряет те свойства, которые в него были заложены изначально

покажи-ка, с цитатами из Java Language Specification, какие свойства там исчезли

опутствующие XML-конфигурации для JavaEE (преодолён аннотациями)

Преодалено смертью JavaEE, когда Oracle от неё отказалось

плохо понимаемый контейнерный DI (вынуждающий применять runtime-аннотации)

используй нормальный DI - Spring Framework. Как он работает - хорошо описано.

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

отдельный доклад есть

Кстати, смотрел недавно. OSGi и модульная Java - это не конкурирующие технологии, у них нет ничего общего - модуль в значении OSGi не то же самое, что в значении Java9. У OSGi модуль - единица плагина (сервиса), который можно загрузить и выгрузить из системы. В Java9 модуль - единица компоновки операционной среды приложения (библиотека).

покажи-ка, с цитатами из Java Language Specification, какие свойства там исчезли

Глубокая рефлексия, когда можно у любого загруженного объекта в JVM менять свойства, строить новые объекты с нужными свойствами. Динамическая загрузка кода из любых источников и выгрузка, если он не нужен. Конечно, модульная архитектура Java9 пока обеспечивает обратную совместимость, введя анонимные и автоматические модули, костыль для контейнерных DI типа Spring, использующих глубокую рефлексию, в виде раскрытого модуля (open module). Новая система просто прибавила работы по дополнительному специфицированию открытости Java-объектов и классов в новых проектах и переписыванию старых.

Преодалено смертью JavaEE, когда Oracle от неё отказалось

Контейнерные DI вряд ли умрут в ближайшее время - для этого нет никаких условий.

используй нормальный DI - Spring Framework. Как он работает - хорошо описано.

Spring Framework появился на свет благодаря несовершенству J2EE 1.4. О каком превосходстве идёт речь, если это просто костыли над устаревшими технологиями, которые преодолены в JavaEE 6 и 7?

iZEN ★★★★★
()

Вопрос.

В какой-либо сишечной среде программирования есть опция «Компилировать при сохранении изменённых исходников»? Если да, как долго она отрабатывает?

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