Pull to refresh

Comments 19

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

На NodeJs можно и на сервере. Особенно если нужно исключить вмешательство пользователя в моделирование, например для игр.

Представьте, что ваш любимый язык программирования, скажем, C. При этом в одном из сравнений C уступает Java, причем существенно, в два раза. Несправедливость! Вы открываете код решения на C и видите, что он написан не очень аккуратно, и явно многое можно многое улучшить и оптимизировать. Если при этом под руку подвернулся свободный вечер, а на столе стоит пара пива, — патча не избежать. В этом подходе и есть основная проблема.
Мне кажется, сначала надо определиться, что считать честным. Если ставить задачу как «определить, какой язык самый быстрый», то тут как раз логично найти спеца по этому языку и дать ему возможность выжать все соки. Тогда мы будем сравнивать именно языки. А если вы говорите
Является ли конечный код типовым, который написал бы любой разработчик
то получается, что мы сравниваем типовых разработчиков. Не говоря уже о том, что понятия «типовой код» и «любой разработчик» — очень размытые.
Я готов только согласиться с тем, что недопустимы хаки, которые подменяют исходную задачу на другую, очень похожую на исходную, но которую очень легко разогнать (и при этом задачу именно в исходной постановке разогнать тем же способом нельзя). И с тем, что количество используемых процессоров тоже лучше сделать одинаковым для всех.
Скорее всего, автор имел ввиду, что алгоритм должен быть как можно более стандартизован, а уже реализацию отдать на откуп языку+стандартные библиотеки и не использовать явных хаков.
А что это даст? Вот тут автор очень напирает на то, что Java — очень быстро работает с деревьями, а malloc и free — «тормозят». Но я как раз с алгоритмами на деревьях (очень разнообразными) работаю в C и C++ последние 10 лет (в разных проектах, я знаю, что это не один язык). И я нигде не видел голого использования malloc и free — во всяком случае в тех частях, где была важна скорость. Часть кода была на Java, впрочем… и даже там были арены! Ну просто дорого выделять миллионы обьектов в «куче» — на любом языке!

Можно ли назвать код, который не используется в реальных проектах «типовым» и код, который используется «читерским»? Вопрос, до некоторой степени, риторический…
Безусловно, алгоритмы должны быть максимально идентичны.
Конечно это не мое требование, а требование сайта: benchmarksgame.alioth.debian.org/u64q/nbody-description.html#nbody
We ask that contributed programs not only give the correct result, but also use the same algorithm to calculate that result.
И с тем, что количество используемых процессоров тоже лучше сделать одинаковым для всех.

Ну в таком случае если так получается, что твой язык не даёт возможности параллелить, а другой — даёт, не значит, что всё нужно в одном треде делать. Но вот максимальное число процессов было бы хорошо ограничить. Это да
#pragma omp к препроцессору отношения не имеет. Это OpenMP, одна из техник параллелизации.
Надо запилить решение второй задачи на С++ на шаблонах. Там можно и 0 секунд получить)
Насколько я помню, там всё запускается на древнем core 2 duo. Поэтому об автоматических векторных оптимизациях (которые делает JVM) можно забыть.

Для джавы, опять же, можно существенно ускорить (в разы) некоторые тесты, если дать определенные ключи JVM, про которые могут быть в курсе даже джуны.

Но всё равно полезно посмотреть, что примерно может каждый ЯП.
Вопрос читерства в таких задачах ооочень интересный — считать ли читерством использование возможностей языка или может сразу банить весь язык, позволяющий тонкое манипулирование?
И какие трики являются читерскими для данной задачи, а какие нет — бывает трудно разделить.

Я смотрел там ранее исходники и отмечал подобные вещи. Но:

— если почитать на сайте stories, то кое что прояснится — сайт был создан для сравнения скриптовых языков, которым жесткие оптимизации обычно не свойственны (но люди нашли способы — молодцы)

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

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

Банить языки программирования позволяющие оптимизации безусловно не нужно,
более того глупо. Однако, если мы будем целенаправленно оптимизировать программы
под задачи и возможности языка, мы получим конкурс программистов — кто лучше оптимизирует, а это совсем другой жанр. То что именно так все и происходит безусловно удручает.
Решения на Erlang — 43 секунды… в зачет не идут, поскольку по факту при их исполнении было задействовано ровно одно процессорное ядро

Вообще, Эрлангу было разрешено использовать 4 ядра:
Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Ну и вы уж определитесь, что считать честным, а что читерством. Модель аллокации памяти в Java, видите ли честная и хорошая, а модель потоков в Эрланге — читерство?
Спасибо за комментарий, я уже начал беспокоиться что никто так и не заступится за erlang :)

С одной стороны вы правы, в решении erlang нет явного читерства, в отличии от Go,
просто исполняющая платформа достаточно умная чтобы понять что на одном ядре
данная программа будет выполнена быстрее. Платформа Erlang в этом смысле достаточно
умная, факт.

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

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

Было бы правильно изменить условие задачи, например сказав что по кольцу нужно крутить
5-ть сообщений, с шагом в 101. Тогда появился бы практический смысл утилизировать
все процессорные ядра.

— Что касается задачи с деревьями, там другая ситуация. Java работает быстро в частности
потому что там сборка мосора идет параллельно, в отличии от решений на C, например.
Однако, разрыв между Java и C слишком велик и даже если бы в Java был указан
однопоточный сборщик мусора, решение все равно отработало бы быстрее. Просто потому
что в любых однопоточных алгоритмах накладные расходы всегда меньше чем в
распределенных.

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

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

Если хочется межпроцессорные коммуникации считать, то надо писать под это конкретный бенчмарк, с жестким распределением процессов по ядрам, и пересылкой сообщений между ядрами на каждой итерации.
UFO just landed and posted this here
На мой взгляд тест хорош тем, что позволяет использовать разные возможности языка программирования при выполненении одинаковых задач.
UFO just landed and posted this here

Чего мне не хватает на BenchmarkGame, так это трекинга версии компилятора/рантайма. На сайте всегда указаны результаты работы на последней версии gcc/GHC/ocamlopt/sbcl/… Иногда при обновлении, к примеру, GHC, ломаются оптимизации, в OCaml в 4.06 сломали обратную совместимость Strings, из-за чего половина программ перестала компилироваться, etc. Я считаю, нужно сделать версию компилятора частью "первичного ключа" (т.е. чтобы ключ был (lang, lang_version, problem_name, solution_version)), это позволит избежать поломки решений и позволит увидеть, как прогрессируют компиляторы со временем.

Sign up to leave a comment.