Подтвердить что ты не робот

JRuby Performance

У меня есть приложение Rails 3.2.2, которое я ищу для запуска с использованием JRuby 1.6.7 (режим 1.9.2).

У меня есть пример приложения, работающего в MRI ruby ​​1.9.3, и типичный запрос возвращается в ~ 40 мс: Завершено 200 OK в 36ms (Просмотров: 27.5ms | ActiveRecord: 8.2ms)

В JRuby с использованием того же запроса в зависимости от страницы в любом месте от 3 до 20 раз медленнее. Для той же операции, что и выше, она занимает ~ 180 мс: Завершено 200 OK в 180 мс (Просмотров: 153.0ms | ActiveRecord: 24.0ms)

Это обычная разница в производительности? Я читал, что JRuby примерно равен скорости с помощью МРТ. Результаты сохраняются на моем Mac и сервере Windows (где, к сожалению, его нужно будет запустить). Упаковка его с Warbler работает под Tomcat так же медленно.

Вышеуказанное время относится к базовому устройству rails, созданному для тестирования JRuby. В более сложном приложении время еще дальше. В этом приложении на некоторых страницах запускается еще один код ruby. Похоже, что чем больше страница зависит от рубина, тем больше разница в производительности, которую я наблюдаю. Я не настраивал JRuby, так как не знаю, с чего начать.

Итак, мои вопросы: это нормально? Что я могу сделать, чтобы настроить JRuby?

4b9b3361

Ответ 1

Is this a normal performance difference?
I have read that JRuby is roughly equal on speed with MRI.

Нет, это не нормально. После того, как JVM разогрелся, запросы Rails под JRuby обычно значительно более эффективны, чем при MRI, как с точки зрения скорости выполнения, так и с помощью сборки мусора.

Похоже, что ваше приложение неправильно сконфигурировано. Первое, что нужно проверить, - это настройка самого Rails - убедитесь, что Rails не находится в режиме разработки и что config.threadsafe! включен в вашей рабочей среде. Режим Threadsafe приведет к тому, что в вашем приложении будет только одна общая копия Rails, загружаемая в память.

Также проверьте, что ваша конфигурация базы данных использует преимущества пула соединений, например. pool: 20 в database.yml.

Наконец, проверьте настройки JVM и JRuby - обе они сильно настраиваются. Вы должны убедиться, что при запуске достаточно памяти, выделенной для JVM, а затем достаточно памяти для нормальной бесперебойной работы вашего приложения; в противном случае JVM будет постоянно вынуждена преждевременно и часто собирать мусор, что значительно ухудшит производительность.

Например, некоторые из параметров для скромно specced VPS могут быть примерно такими:

-Xmx500m -Xss1024k -Djruby.memory.max=500m -Djruby.stack.max=1024k

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

Тем не менее, JRuby, вероятно, потребляет меньше памяти, чем общая сумма нескольких процессов Rails в MRI, вам определенно нужно будет выделить немного больше для одного процесса JVM. Будьте щедры к JRuby, и JRuby вознаградит вас за вашу доброту: -)

Подробнее о настройке JRuby и JVM вы можете узнать здесь: https://github.com/jruby/jruby/wiki/PerformanceTuning

Обновление

Вам не нужно устанавливать config.threadsafe! в Rails 4.0 и выше; по умолчанию это потокобезопасно.

Ответ 2

Я вижу одно и то же поведение, но имейте в виду, что JRuby требует значительно дольше разогреваться. На самом деле я немного оптимистичен, что JRuby в конечном итоге наверстает упущенное.

Можно сделать это "разогрев" быстрее, установив несколько параметров. Компилятор Ruby → Java Bytecode можно научить JIT компилировать каждый метод при первом вызове, установив следующий env var:

export JRUBY_OPTS="-J-Djruby.jit.threshold=1 -J-Djruby.jit.max=16384"

Для меня, после обновления страницы Rails несколько раз, она все же на 2-3 раза медленнее, чем MRI Ruby, но по крайней мере в 3 раза быстрее, чем раньше.

Также имейте в виду, что java runtime - это JIT, компилирующий байт-код java для машинного кода аналогичным образом, но этот JIT не будет использоваться, пока метод не будет вызван 10.000x при использовании времени выполнения сервера. Это может быть настроено также.

export JRUBY_OPTS="-J-Djruby.jit.threshold=10 -J-Djruby.jit.max=16384 -J-XX:CompileThreshold=10" -J-XX:ReservedCodeCacheSize=128M"

С этими параметрами JRuby on Rails дает одинаковую или лучшую производительность, чем MRI.

Обратите внимание, что эти параметры предназначены только для нетерпеливого бенчмаркинга! В действительности это почти всегда плохая идея, чтобы запустить компиляцию JIT агрессивно; Вы тратите драгоценное время и память на JIT-компиляцию кода, который может запускаться только несколько раз. Это показывает, однако, как возможная производительность JRuby может быть лучше, чем вы ожидаете, исходя из начальных прогонов.

Сообщите мне, работает ли это для вас.

Ответ 3

Перейдите на jruby 1.6.8 или jruby 1.7.x с помощью JAVA 7!

Удивительная производительность.

У нас была одна и та же проблема, и теперь она очень быстро работает (просто переключая версии).