Производительность Clojure при обработке чисел

Я не уверен, принадлежит ли это StackOverflow или группе Clojure Google. Но группа, похоже, занята обсуждением числовых улучшения для Clojure 1.2, поэтому я попробую здесь:

http://shootout.alioth.debian.org/ содержит несколько тестов производительности для различных языков.

Я заметил, что Clojure отсутствует, поэтому сделал версию на Clojure. проблема с n-телом.

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

  • в 10 раз быстрее, чем Python/Ruby/Perl
  • в 4 раза медленнее, чем C/Java/Scala/Ada
  • примерно на уровне OCaml, Erlang и Go

Меня вполне устраивает такой уровень производительности.

Мой вопрос к гуру Clojure:

  • Есть ли очевидные улучшения, которые я упустил, либо с точки зрения скорости, либо с точки зрения краткости кода или удобочитаемости (без ущерба для скорости)?
  • Считаете ли вы, что это показатель производительности Clojure по сравнению с Python/Ruby/Perl, с одной стороны, и Java/C, с другой?

Обновить

Другие тестовые программы Clojure 1.1 для перестрелки здесь, включая задачу n-body.


person j-g-faustus    schedule 26.06.2010    source источник
comment
Я должен представить, что JVM сыграет здесь большую роль. Какую JVM вы используете? Вы используете тот же, что и для перестрелки?   -  person Adam Gent    schedule 26.06.2010
comment
Java 1.6.0, стандартная Java, поставляемая с OS X 10.6. Это примерно та же JVM (я: 1.6.0_20, перестрелка: 1.6.0_18), но другой компьютер, чем перестрелка. Я запускал как Clojure, так и тестовую реализацию Java локально. Я оценил относительную производительность, взяв за основу Java и соответствующим образом масштабируя результаты перестрелок.   -  person j-g-faustus    schedule 26.06.2010
comment
Ваш код выглядит довольно хорошо. Я ожидаю, что с примитивными улучшениями в 1.2 вы сможете довольно близко приблизиться ко времени Java. Пробовали запускать через профилировщик? Я подозреваю, что что-то где-то добавляет накладные расходы на бокс или вызов функции, которые вам вредят.   -  person mikera    schedule 26.06.2010
comment
О, это классный проект и отличный вклад в бушующие в настоящее время дебаты, о которых вы упоминаете. Я буду ждать более подробных ответов ... Мне также интересно, как ваш код будет работать, если его прокатить по новым веткам. Мог бы дать этому шанс - или вы бы? Кстати, все это абсолютно интересно для ggroup, особенно сейчас; может быть, вы могли бы опубликовать его в теме, которую я упоминаю ниже?   -  person Michał Marczyk    schedule 26.06.2010
comment
@mikera: Согласно профилировщику, для intCast (Object) используется ~ 4% ЦП, что я еще не смог отследить. Еще 5% на даблкаст(double), от которых можно было бы избавиться. Так что, возможно, до ~ 10% улучшений. Кроме того, профилировщик не показывает никаких низко висящих плодов.   -  person j-g-faustus    schedule 26.06.2010
comment
@Michal: Хорошо, я опубликую это в теме, на которую вы ссылаетесь. Я мог бы попробовать это в одной из новых веток, если/когда у меня будет время, но эти ветки кажутся целью, которая движется так быстро, что я не думаю, что смогу угнаться за ними. Не стесняйтесь попробовать, если вам интересно :)   -  person j-g-faustus    schedule 26.06.2010


Ответы (3)


Здесь не поток ответов :), но, очевидно, некоторый интерес, поэтому я попытаюсь ответить на свой вопрос с тем, что я узнал за последние несколько дней:

  • С подходом к оптимизации 1.1 (примитивы Java и изменяемые массивы) примерно в 4 раза медленнее, чем оптимизированная Java, примерно так же быстро, как и идет.
  • Конструкции 1.2 definterface и deftype более чем в два раза быстрее, примерно в 1,7 раза (+70%) от Java с более коротким, простым и чистым кодом, чем в 1.1.

Вот реализации:

Подробнее, включая "извлеченные уроки", версию JVM и скриншоты профилирования.

С субъективной точки зрения, оптимизация кода 1.2 была проще простого по сравнению с оптимизацией 1.1, так что это очень хорошая новость для Clojure. (На самом деле близко к удивительному :)

При тестировании версии 1.2 использовалась текущая основная ветка, я не пробовал ни одну из новых числовых веток. Из того, что я могу почерпнуть, новые идеи, обсуждаемые в настоящее время

  • может сделать неоптимизированные числа быстрее
  • может ускорить версию 1.1 этого теста
  • вероятно, не ускорит версию 1.2, она уже настолько «близка к металлу», насколько это возможно.

Отказ от ответственности:

  • Clojure 1.2 еще не выпущен, поэтому результаты тестов 1.2 являются предварительными.
  • Это один из конкретных ориентиров для физических расчетов. Это относится к обработке чисел с плавающей запятой, но не имеет отношения к производительности в таких областях, как синтаксический анализ строк, параллелизм или обработка веб-запросов.
person j-g-faustus    schedule 29.06.2010
comment
Вы должны попробовать числовые ветки, просматривая ваш код, я вижу места, где вы без необходимости получите бокс под основной веткой 1.2. - person dnolen; 30.06.2010
comment
Спасибо за совет. Эквивалентная ветка оказала некоторое влияние на версию 1.1, но не заметно для версии 1.2. Могут быть альтернативные реализации, где разница более существенна. Эквивалентная ветка по-прежнему выглядит хорошо, особенно подсказки примитивного типа и :static. - person j-g-faustus; 02.07.2010
comment
Большое спасибо за очень интересный вклад. Мне особенно понравилось читать подробный анализ. Я скомпилировал версию 1.2 и сравнил ее с примером Java в нескольких прогонах, и в среднем она была только в 1,5 раза медленнее. У меня возникли два вопроса. Как вы указали в своем анализе, код не идиоматичен, поскольку он использует изменяемые переменные. Насколько медленнее будет выполняться код, если будут использоваться неизменяемые переменные? Сколько усилий потребуется для распараллеливания изменяемой или неизменяемой версии? - person Stefan Schmidt; 05.07.2010
comment
Спасибо, рад, что вам понравилось. 1.5x: Звучит неплохо, мы примерно на одном уровне друг с другом. Изменяемый и неизменяемый: я не пробовал неизменяемый, не стесняйтесь попробовать. Я бы ожидал где-то между изменчивым 1.2 и изменчивым 1.1, но трудно предположить. Распараллеливание: эту конкретную задачу трудно распараллелить в любом случае. В общем, многопоточность с изменяемыми значениями намного сложнее, чем с неизменяемыми значениями, что является одной из причин, по которой Clojure по умолчанию использует неизменяемые значения. - person j-g-faustus; 05.07.2010
comment
Кстати: вот реализация Clojure гораздо более крупного теста, включающего параллелизм и анализ файла журнала: meshy.org/2009/12/13/widefinder-2-with-clojure.html Стоит прочитать, если вам нужна масштабная производительность. - person j-g-faustus; 05.07.2010
comment
Знаете ли вы, есть ли какая-то особая причина, по которой результат Clojure не указан в таблице тестов Widefinder 2? wikis.sun.com/display/WideFinder/Results - person Stefan Schmidt; 08.07.2010
comment
Мне было интересно то же самое. Комментарии Тима Брэди, кажется, предполагают, что он хотел бы, чтобы рефакторинг был более общим tbray.org/ongoing/When/200x/2009/12/15/Osborne-WF2-Clojure Я могу только догадываться, что автор чувствовал, что потратил на это достаточно времени и не заморачиваться с рефакторингом. Но нет, я не знаю причины. - person j-g-faustus; 09.07.2010

Интересно, может ли Cantor быть вам полезным — это высокопроизводительная математическая библиотека для Clojure. См. также эту тему в группе Google. , о похожем проекте в контексте новой примитивной арифметики.

person Michał Marczyk    schedule 26.06.2010
comment
Cantor выглядит полезным, я посмотрю. Спасибо! - person j-g-faustus; 26.06.2010

Это немного старый вопрос, и существующие ответы несколько устарели, поэтому я хотел бы добавить обновление по состоянию на середину 2013 года для тех, кто интересуется «обработкой чисел» в Clojure.

В области числовых вычислений Clojure произошло много событий:

  • Вышла версия Clojure 1.5, в которой значительно улучшена поддержка числовых операций. В большинстве случаев теперь можно приблизиться к чистой скорости Java.
  • Специальная группа новостей – Numerical Clojure
  • core.matrix теперь предоставляет идиоматический API для матричной математики и числовых вычислений. который поддерживает несколько внутренних реализаций (включая собственные библиотеки BLAS)

Отказ от ответственности: я являюсь сопровождающим / участником нескольких из вышеперечисленных.

person mikera    schedule 09.09.2013