Просматривая сегодня «Ruby Inside», наткнулся на статью Justin Kulesza Is Your Application Running with Ruby – Slow?. Статья от 6 ноября, но Хабре об этой ситуации ни слова. А суть статьи вот в чем: ребята переносили свое приложение с сервера на Solaris на сервер с Ubuntu и использовали RVM для компиляции Ruby. Однако после переноса они заметили, что приложение стало как-будто бы тормознутее. Сначала погрешили на железо, но быстро выяснили, что дело в RVM, а именно в том, что RVM совершенно не использует оптимизацию при компиляции.
Диагностика проблемы очень простая:
$ time ruby -e "count = 0; while(count < 100000000); count = count + 1; end; puts count"
100000000
real 0m9.019s
user 0m8.933s
sys 0m0.016s
«Нормальное» время выполнения должно быть не выше ~4 секунд.
Плюс отсутствие флагов оптимизации в ~/.rvm/log/your.ruby.version/make.log:
CC = gcc
LD = ld
LDSHARED = gcc -shared
CFLAGS = -I/home/user/.rvm/usr/include -fPIC
XCFLAGS = -include ruby/config.h -include ruby/missing.h -fvisibility=hidden -DRUBY_EXPORT
CPPFLAGS = -I. -I.ext/include/x86_64-linux -I./include -I.
DLDFLAGS = -Wl,-soname,libruby.so.1.9
SOLIBS = -lpthread -lrt -ldl -lcrypt -lm
В CFLAGS должно присутствовать -O3.
Проверил на своем сервере — и правда, проблема имеет место быть.
В статье приводится такое решение:
$ echo "rvm_configure_env=(CFLAGS=-O3)" > ~/.rvmrc
И затем:
$ rvm reinstall your.ruby.version
Тем не менее, на текущий момент все еще проще:
$ rvm get head && rvm reinstall your.ruby.version
А кроме того в 'head'-версии RVM доступен небезывестный патч от funny-falcon для последней версии Ruby — 1.9.3-p327, который делает Ruby еще быстрее (особенно при загрузке приложения). Установка также проста:
$ rvm install 1.9.3 -n perf --patch falcon
$ rvm use 1.9.3-perf --default
После переустановки сервер показал прирост скорости более чем в 2 раза:
$ time ruby -e "count = 0; while(count < 100000000); count = count + 1; end; puts count"
100000000
real 0m4.117s
user 0m4.032s
sys 0m0.012s
Так что проверяйте свои сервера, ускоряйте свои приложения.
Автор: Svyatov