Я вижу некоторые серьезные замедления в "некоторых" частях приложения Clojure. У кого-нибудь есть какие-либо реальные подсказки о том, как они настроили настройку производительности в приложении Clojure?
Реальный мир Clojure советы по настройке производительности?
Ответ 1
Мои личные советы:
- Сначала проверьте свой алгоритм - вы несете стоимость O (n ^ 2), когда это действительно должно быть O (n.log n)? Если вы выбрали плохой алгоритм, остальная настройка - пустая трата времени.
- Имейте в виду общие "gotchas", такие как O (n) стоимость прохождения списка/последовательности.
- Воспользуйтесь преимуществами функций Clojure, таких как стоимость O (1) копирования большой постоянной структуры данных или стоимости O (log32 n) для доступа к карте/множеству/вектору.
- Выберите из Clojure основных конструкций мудро:
- атом отлично работает, когда вам нужны некоторые изменяемые данные, например. обновление некоторых данных в цикле
- Если вы собираетесь последовательно перемещать некоторые данные, используйте список, а не вектор или карту, так как это позволит избежать создания временных объектов при прохождении последовательности.
- При необходимости используйте deftype/defrecord/defprotocol. Они в значительной степени оптимизированы и, в частности, должны быть предпочтительными для детерструкции/мультиметодов начиная с Clojure 1.2 и далее.
- Воспользуйтесь возможностями Clojure concurrency:
- pmap и будущее - это относительно простые способы использования нескольких ядер при одновременном выполнении нескольких независимых вычислений.
- Помните, что из-за Clojure неизменяемых устойчивых структур данных создание и работа с несколькими копиями данных очень недорогая. Вам также не нужно беспокоиться о блокировке при съемке снимков.....
- Если вы взаимодействуете с Java-кодом, используйте "(set! * warn-on-reflection * true)" и устранить все предупреждения отражения. Отражение - одна из самых дорогих операций, и будет действительно замедлять ваше приложение, если оно будет сделано повторно.
- Если вам по-прежнему нужна большая производительность, укажите наиболее важные для производительности компоненты вашего кода (например, 5% строк, в которых приложение тратит 90% + процессорного времени), подробно проанализируйте этот раздел и разумно примените следующие правила:
- Избегайте лень. Лень - отличная функция, но с некоторыми дополнительными накладными расходами. Имейте в виду, что многие из Clojure общих функций последовательности/списка являются ленивыми (например, для, map, partition). loop/recur, dotimes и уменьшить ваши не ленивые друзья.
- Используйте примитивные подсказки и непроверенную арифметику, чтобы сделать арифметический/числовой код быстрее. Примитивы намного быстрее, чем Clojure арифметика BigInteger по умолчанию.
- Сократить выделение памяти - старайтесь избегать создания слишком большого количества ненужных промежуточных данных (векторов, списков, карт, не примитивных чисел и т.д.). Все распределения налагают небольшое количество дополнительных накладных расходов, а также приводят к большему количеству дополнительных пауз GC с течением времени (это может вызвать большую озабоченность, если вы пишете игровое/мягкое приложение в реальном времени.)
- (Ab) использует массивы Java - не очень идиоматично в Clojure, но aget/aset/areduce и друзья очень быстрые (они извлекают выгоду из множества оптимизаций JVM!!). (Ab) используют примитивные массивы для дополнительных бонусных очков.
- Использовать макросы - генерировать безошибочный, но быстрый код во время компиляции, где это возможно.
Выполнение всего вышеописанного должно получить довольно хорошую производительность из Clojure кода - с тщательной настройкой, я обычно был достаточно близок к чистой производительности Java, что довольно впечатляет для динамического языка!
Ответ 2
Вы можете использовать JVisualVM для профилирования кода Clojure (см. JVisualVM и Clojure для примера). Это должно по крайней мере указывать на правильное направление медленного кода.
Ответ 3
Этот вопрос охватывает профилирование с помощью Clojure: Инструмент профилирования для Clojure?
Я уверен, что вы найдете там хорошие советы.
Затем прямо из устья лошади: http://clojure.org/getting_started#Getting%20Started-Profiling