LINUX.ORG.RU

programming languages performance benchmarks

 , , ,


2

1

А какие еще есть онлайн системы для сравнения производительности реализаций языков программирования кроме всем известного benchmarksgame, который весьма специфичен + там мало языков, а когда-то было намного больше. Фреймворки и открытые библиотеки на основе которых можно сделать нечто подобное тоже приветствуются. Что бы вы хотели видеть в таком сервисе, что можно вообще улучшить?

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

Могу я рассказать. Проблема в том, что вместо сравнения начинается состязание.

Например, на том самом benchmarksgame в расчёте множества Мандельброта Haskell быстрее, чем C. Но за счёт того, что вместо прямолинейного

import Data.Bool
import Data.Complex (Complex((:+)), magnitude)
 
mandelbrot
  :: RealFloat a
  => Complex a -> Complex a
mandelbrot a = iterate ((a +) . (^ 2)) 0 !! 50
 
main :: IO ()
main =
  mapM_
    putStrLn
    [ [ bool ' ' '*' (2 > magnitude (mandelbrot (x :+ y)))
      | x <- [-2,-1.9685 .. 0.5] ]
    | y <- [1,0.95 .. -1] ]

написан монстр https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/mandelbrot-ghc-3.html

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

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

monk ★★★★★
()

Большинство программ на Java быстрее программ на C++ по параметрам времени сборки из исходников (у Java компиляция в разы быстрее) и времени выполнения рабочего кода (здесь играют свою роль оптимизации JIT во время выполнения Java-кода).

Ничего удивительного в том, что системы биллинга пишутся в основном на Java. Удивительно то, что для обучения пропихивают везде Python и C++. Может надеются научить крокодила летать?

iZEN ★★★★★
()

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

плюс было бы удобно смотреть в разрезе платформы/железа

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

времени выполнения рабочего кода (здесь играют свою роль оптимизации JIT во время выполнения Java-кода).

Как правило, нет. Потому что в Java в широко используемых библиотеках принято больше слоёв абстракций. И никакой JIT после этого спасти не может.

Ничего удивительного в том, что системы биллинга пишутся в основном на Java.

Для биллинга важна не скорость, а стабильность. Ошибка на C++ приводит к сегфолту в случайном месте программы. Ошибка на Java приводит к стекстрейсу в окрестности того места, где сделана ошибка.

А вот для компьютерных игр важна скорость и там используют C++ везде, где возможно (то есть кроме телефонов).

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

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

Ещё не хватает сравнения именно языковых конструкций. Вот сравнивали yield в разных языках: clojure после common lisp - насколько омерзительно и в чём именно? (комментарий)

То, что yield на Racket call/cc на два десятичных порядка медленнее прямого перебора было слегка неожиданно (предполагал один порядок).

Аналогично, цена ООП в разных языках существенно разная (от почти нулевой для C++ до очень существенной в PERL и Racket).

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

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

Что хотел бы видеть я в первую очередь - это сравнение *идиоматического* кода на разных языках, на сколько производителен _такой_ код. И как опция - вот эти вот все экстремально заоптимизированные версии и сравнивать их между собой. Перформанс ооп. А что еще можно было бы сделать интересного?

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

Кстати, тот бенч для CL vs racket еще не завершен, мне некогда было еще пару идей протестить, а потом я забыл. Да, интересно ооп и языковые конструкции, библиотечные или встроенные структуры данных. Возвращаясь к изначальному вопросу - кроме benchmarkgames не знаешь еще каких-то подобных онлайн-сервисов? Ну, или все то же самое, но без веб-мордочки, а в каком-то другом виде. В текущей версии benchmarkgames я не нашел, как сравнить между собой произвольные языки и версии программ из списка. Короче, сервис какой-то весьма ограниченный, даже больше, чем ранее, но и альтернатив не видать.

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

плюс было бы удобно смотреть в разрезе платформы/железа

Различные ос, компиляторы и вот это вот все? На счет железа тоже как-то наверное можно организовать на разных vps, но имхо это не особо приоритетно.

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

А вот для компьютерных игр важна скорость и там используют C++ везде, где возможно (то есть кроме телефонов).

Игры разные бывают, то для шутеров и шейдеров и прочего графона оно критично (и то на современном железе неизвестно на сколько), но во-первых это достаточно специфический класс игр, не возьмусь оценивать их рыночную долю, но класс этот не самый большой имхо - есть же еще всякие онлайн серверы для ммо, которые на С++ тоже писать, а во-вторых скорость разработки тоже важна. Если у тебя игра не требовательная к производительности на самом топовом уровне и основная ее суть в красивой рисованной графике без 3d, хорошей истории и глубоко проработанном лоре, С++ тут вообще не к месту.

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

Ничего удивительного в том, что системы биллинга пишутся в основном на Java.

За неимением лучшего, можно и на java конечно...

Удивительно то, что для обучения пропихивают везде Python и C++. Может надеются научить крокодила летать?

С++ низкоуровневый язык, в котором можно подняться до достаточно высокого уровня абстракций, он близок к железу и не обязывает использовать ООП везде. Python простой и достаточно выразительный. Как по мне, это неплохие языки для обучения. К списку я бы еще добавил Lisp, assembler и *HDL.

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

Lisp может и интересный язык, но учить новичку его новичку бесполезно, потому что он не сможет его где-нибудь применить. А вот если он выучит питон, то он 100% сможет найти себе open source проект по душе.

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

Очевидно, что лисп учат не для того, чтобы устроиться на галеру, открытых проектов на лиспе очень много - открываешь гитхаб и выбираешь себе любой по вкусу. Lisp в первую очередь надо учить для того, чтобы понимать, как выглядит нормальный язык программирования, а не куций огрызок неосиляторов CS. И для своих проектов, стартапов. А так же тем, кто уже на чем-то программировал и понял, что ему нужны фичи которые дает лисп - метапрограммирование, repl, высокоуровневый и при этом очень производительный язык, нормальная среда разработки, рестарты, исследовательская среда для создания _быстро_ работающих прототипов, которые потом не надо переписывать на что-либо другое. Сайты можно и на пхп писать, а вот питон, который сейчас чуть ли не мейнстрим в machine learning и data analysis - очень плохо справляется с возложенными на него задачами. Конечно лучше, чем java, C++ и js, но намного хуже любого лиспа. И если у тебя есть значительный опыт работы с питоном ты быстро начинаешь замечать, что в нем не хватает то этого, то того. И тут хопа Lisp.

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

Согласен, Lisp - язык хороший, но не в контексте: [...]Как по мне, это неплохие языки для обучения. К списку я бы еще добавил Lisp, assembler и *HDL. Хотя, лично мой опыт с Lisp ограничивается, к сожалению, написанием конфига для Emacs.

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

Согласен, Lisp - язык хороший, но не в контексте:
Хотя, лично мой опыт с Lisp ограничивается, к сожалению, написанием конфига для Emacs.

А чем плохо начинать обучение сразу с нормального языка? Не elisp, а скорее схема или CL. Хотя и он хорош в разрезе практического применения (emacs).

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

И если у тебя есть значительный опыт работы с питоном ты быстро начинаешь замечать, что в нем не хватает то этого, то того. И тут хопа Lisp

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

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

А чем плохо начинать обучение сразу с нормального языка? Не elisp, а скорее схема или CL. Хотя и он хорош в разрезе практического применения (emacs)

В том, что идея языка, которым легко оперировать машиной, неизбежно приводит к тому, что этим языком тяжело оперировать человеком. Был когда-то самый замечательный и понятный машине ЯП — ассемблер, к которому даже макросы на лиспе писали. Но потом что-то пошло не так.

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

Ну в Lisp совершенно другие практики, так, например, человек, который выучил C++, сможет легко переключиться на Java или на python. В Lisp и схемах много моментов, которых в других языках нет. Возьмем, например, Racket и local binding: define, let, let*, letrec - 4 способа создать переменную, у новичка уже будет неразбериха - что ему использовать. Еще нет стандартных циклов, то есть некоторые операции, как мне кажется, становятся не совсем тривиальными. Мне кажется классные языки для обучения это Python, за его простоту, и Pascal, как язык он тоже хорош и достаточно строгий, но он мертв.

Мне просто интересно как будет выглядеть код на Racket или CL, в котором, для простоты, зануляется часть под главной диагональю, включая ее. На octave это будет так:

N = 10;
A = ones(N);
A

for i = 1 : length(A)
    for j = 1 : length(A)
        if(j <= i)
            A(i, j) = 0;
        endif
    endfor
endfor
A
A =

   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1
A =

   0   1   1   1   1   1   1   1   1   1
   0   0   1   1   1   1   1   1   1   1
   0   0   0   1   1   1   1   1   1   1
   0   0   0   0   1   1   1   1   1   1
   0   0   0   0   0   1   1   1   1   1
   0   0   0   0   0   0   1   1   1   1
   0   0   0   0   0   0   0   1   1   1
   0   0   0   0   0   0   0   0   1   1
   0   0   0   0   0   0   0   0   0   1
   0   0   0   0   0   0   0   0   0   0

Мне кажется, если бы не end’ы, то смотрелось бы весьма кратко и лаконично.

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

которые питон используют в роли эдакого MS Office

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

Тоесть, язык вообще не играет никакой роли — роль играет только наличие готовых решений.

Но почему-то эта экосистема сформировалась именно вокруг питона при том что уже был R и есть julia (нужность которой весьма сомнительна).

И тут стоит большой вопрос по поводу того, можно ли этого человека научить писать на лиспе.

Не все исследователи (данных) совсем не-программисты. И если знаешь вкус устриц, его тяжело забыть. Будет экосистема на лиспе - будут писать на лиспе, потому что программирование в смысле построения архитектур и написания красивых библиотек это не та задача, которой занимается современный DS.

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

здесь играют свою роль оптимизации JIT

Нет. Ты не понимаешь как это работает. Сильно зависит «холодная» jvm или «прогрета». А у С++ бинарник не изменятся и результаты воспроизводимы и зависят только от загрузки системы.

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

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

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

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

Будет экосистема на лиспе - будут писать на лиспе

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

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

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

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

https://github.com/ecraven/r7rs-benchmarks (результат: https://ecraven.github.io/r7rs-benchmarks/)

https://github.com/the-benchmarker/web-frameworks (результат: https://web-frameworks-benchmark.netlify.app/result). Кстати, на этой задаче PHP показал результат втрое быстрее, чем C и С++.

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

И чем Emacs не подходит? У меня Emacs ни разу не падал. Максимум на меня, при ошибке обновления Doom emacs, падала огромная лапша «логов» в виде s-expr.

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

Хорошо, не емакс, а CL. Проект пишет несколько человек, каждый свой модуль. Как вы согласуете типы классов и какие гарантии даст компилятор?

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

Ну, насколько мне известно в CL никак и никакие, потому что CL знаменит своим monkey patching’ом. Подробнее, наверно, может рассказать @monk.

В Racket с модулями все хорошо, чужой код не может повлиять на твой модуль, еще есть typed racket, который вводит типы, для примера: https://docs.racket-lang.org/ts-guide/more.html

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

Мне просто интересно как будет выглядеть код на Racket или CL

У тебя там предположительно ошибка в j = 1 : length(A). Там же длина одной строки должна быть.

CL:

(let* ((N 10)
       (a (make-array (list N N) :initial-element 1)))
  (print a)
  (loop for i from 0 below (array-dimension a 0) do
    (loop for j from 0 below (array-dimension a 1) do
      (when (<= j i) (setf (aref a i j) 0))))
  a)

#2A((1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1))
#2A((0 1 1 1 1 1 1 1 1 1)
    (0 0 1 1 1 1 1 1 1 1)
    (0 0 0 1 1 1 1 1 1 1)
    (0 0 0 0 1 1 1 1 1 1)
    (0 0 0 0 0 1 1 1 1 1)
    (0 0 0 0 0 0 1 1 1 1)
    (0 0 0 0 0 0 0 1 1 1)
    (0 0 0 0 0 0 0 0 1 1)
    (0 0 0 0 0 0 0 0 0 1)
    (0 0 0 0 0 0 0 0 0 0))

Racket:

#lang racket
(define N 10)
(define a (build-vector N (λ (n) (make-vector N 1))))
(pretty-print a)
(for* ([i N] [j N] #:when (j . <= . i))
  (vector-set! (vector-ref a i) j 0))
a

'#(#(1 1 1 1 1 1 1 1 1 1)
   #(1 1 1 1 1 1 1 1 1 1)
   #(1 1 1 1 1 1 1 1 1 1)
   #(1 1 1 1 1 1 1 1 1 1)
   #(1 1 1 1 1 1 1 1 1 1)
   #(1 1 1 1 1 1 1 1 1 1)
   #(1 1 1 1 1 1 1 1 1 1)
   #(1 1 1 1 1 1 1 1 1 1)
   #(1 1 1 1 1 1 1 1 1 1)
   #(1 1 1 1 1 1 1 1 1 1))
'#(#(0 0 0 0 0 0 0 0 0 0)
   #(1 0 0 0 0 0 0 0 0 0)
   #(1 1 0 0 0 0 0 0 0 0)
   #(1 1 1 0 0 0 0 0 0 0)
   #(1 1 1 1 0 0 0 0 0 0)
   #(1 1 1 1 1 0 0 0 0 0)
   #(1 1 1 1 1 1 0 0 0 0)
   #(1 1 1 1 1 1 1 0 0 0)
   #(1 1 1 1 1 1 1 1 0 0)
   #(1 1 1 1 1 1 1 1 1 0))
monk ★★★★★
()
Ответ на: комментарий от Djanik

Примерно те же, что и в питоне. Если для экспортируемых функций не забывать писать declare (описывать тип), то при каждом вызове такой функции тип аргументов будет проверяться. Проверка типа класса быстрая – там одно число в структуре.

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

И как работать, когда ошибка каждый раз будет вываливаться у заказчика?

А компилятор статического языка не даст тебе к примеру вместо complex использовать double и найдет еще более сложные ошибки.

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

Компилятор статических языков дает некие гарантии

Только ими мало кто пользуется. В GTK те же проверки при запуске функции и потом сыпется

Gdk-CRITICAL **: 10:44:43.426: IA__gdk_drawable_get_size: assertion 'GDK_IS_DRAWABLE (drawable)' failed

Но всем пофиг и пишут специальную заглушку, чтобы это не видеть: https://askubuntu.com/questions/505594/how-to-stop-gedit-and-other-programs-from-outputting-gtk-warnings-and-the-like

С другой стороны в динамическом языке нет прокрустова ложа статических типов. Можешь попробовать написать тип для map. На большинстве статических языков программирования или потерпишь неудачу или получишь что-то вроде: первый аргумент любая функция, остальные – любые списки.

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

Возьмем, например, Racket и local binding: define, let, let*, letrec - 4 способа создать переменную, у новичка уже будет неразбериха - что ему использовать

Нет никакой неразберихи, в доках все четко (и даже с примерами!) расписано.

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

В GTK те же проверки при запуске функции и потом сыпется

Потому что в GTK никаких статических проверок нет, это голая динамика на С.

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

У тебя там предположительно ошибка в j = 1 : length(A). Там же длина одной строки должна быть.

А Octave/Matlab возвращает длину наибольшего измерения, а в квадратной матрице, все равно:

octave:1> A = [1 2; 3 4], length(A)
A =

   1   2
   3   4

ans = 2
octave:2> A = [1 2; 3 4; 5 6], length(A)
A =

   1   2
   3   4
   5   6

ans = 3

Спасибо за примеры! Только почему сравнение в Racket выглядит так: (j . <= . i)? Зачем нужны эти точки? Почему не (<= j i)?

P.S. А понял в Racket <= работает немного по другому, получается надо использовать (>= j i)?

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

И если не совпадет, приложение вызовет отладчик?

В CL вызовет отладчик и позволит что угодно поправить. На марсианском ровере этим пользовались, насколько я знаю: https://franz.com/success/customer_apps/scheduling/nasa.lhtml

В Racket будет прерывание работы с выводом стека и указанием, какой модуль виноват.

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

Только почему сравнение в Racket выглядит так: (j . <= . i)? Зачем нужны эти точки? Почему не (<= j i)?

Это одно и то же. (a b c) === (b . a . c). Специально для читабельности бинарных операций.

Получается надо использовать (>= j i)

Нет. Все логические операции работают также, как и везде.

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

Так C – статический язык программирования. Разве нет? А GTK как раз пример того, где статических типов C не хватило.

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

Да, там все с примерами и с доками, но мне почему-то кажется, что новички первым делом не доки с примерами читают: https://duckduckgo.com/?q=racket+difference+between+define+let+let*+letrec&t=ffab&ia=web Лично у меня первые две выдачи со stackoverflow и только потом ссылка на официальные доки.

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

Нет никакой неразберихи, в доках все четко (и даже с примерами!) расписано.

Немножко есть. Можно выкинуть группу let и вместо них использовать только define. Можно использовать только группу let (как сделано в CL). Они взаимозаменяемы. Также, как из четырех сравнений на равенство достаточно оставить два (глубокое и мелкое). Но это уже традиции и совместимость.

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

Лично у меня первые две выдачи со stackoverflow и только потом ссылка на официальные доки.

Это потому, что ты его чаще читаешь (и ищешь через этот поисковик). У меня первая ссылка – доки, вторая реддит, третья – снова доки, и только четвёртая – stackoverflow

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

Большинство программ на Java быстрее программ на C++ по параметрам времени сборки из исходников (у Java компиляция в разы быстрее)

Сталкивался с gradle-проектами, в которых изменение одного файла приводило к какой-то непонятной перекомпиляции на 2-3 минуты. А также видел cpp проекты, в которых изменение одного файла приводило только к его перекомпиляции и длилось в пределах 2-3 секунд.

времени выполнения рабочего кода (здесь играют свою роль оптимизации JIT во время выполнения Java-кода)

<sarcasm>Ждем видео и аудиокодеков на Java, систем реального времени на Java, высокопроизводительных вычислительных пакетов на Java и т. д. и т. п.</sarcasm>

Как можно на чистом глазу нести чушь про производительность Java, когда там даже List<Integer> медленнее std::vector<int> на несколько порядков. Передавай привет боксингу!

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

А GTK как раз пример того, где статических типов C не хватило

А почему не пример того, как разработчики GTK не смогли реализовать классы? А Страуструп смог.

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

систем реального времени на Java

Есть такие системы

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

А Страуструп смог.

Страуструп написал другой язык программирования.

Также на C++ нельзя сделать map из Racket. Но можно написать компилятор Racket.

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