Ускоряем запуск Ruby on Rails используя набор патчей RVM railsexpress

Эта статья для тех, кто хочет ускорить запуск рельс, а заодно ускорить работу интерпретатора ruby.
О том как установить RVM (Ruby version manager) уже написано много статей, поэтому я перейду сразу к делу.
Список патчей в RailsExpress для Ruby 1.9.3-p362
(это последняя версия руби на момент написания статьи)
Applying patch railsexpress/01-fix-make-clean.patch
Applying patch railsexpress/02-railsbench-gc.patch
Applying patch railsexpress/03-display-more-detailed-stack-trace.patch
Applying patch railsexpress/04-fork-support-for-gc-logging.patch
Applying patch railsexpress/05-track-live-dataset-size.patch
Applying patch railsexpress/06-webrick_204_304_keep_alive_fix.patch
Applying patch railsexpress/07-export-a-few-more-symbols-for-ruby-prof.patch
Applying patch railsexpress/08-thread-variables.patch
Applying patch railsexpress/09-faster-loading.patch
Applying patch railsexpress/10-falcon-st-opt.patch
Applying patch railsexpress/11-falcon-sparse-array.patch
Applying patch railsexpress/12-falcon-array-queue.patch


1. Указываем RVM с какими параметрами надо компилить Ruby

Для этого нужно создать файл .rvmrc в домашнем каталоге.
$ nano -e $HOME/.rvmrc

И явно указать RVM с какими параметрами компилировать Ruby.
CFLAGS="-march=native -O2 -pipe -fomit-frame-pointer"
rvm_configure_env=(CFLAGS="-march=native -O2 -pipe -fomit-frame-pointer")

Здесь параметр -march=native указывает компилятору на автоматический выбор типа процессора и поддерживаемых этим процессором возможностей. Если вы точно знаете тип своего процессора, то можно указать, например, -march=prescott

Сохранить изменения: [ctrl + X], потом [Y] — чтобы выйти и сохранить в nano.

2. Обновляем списки доступных версий Ruby в RVM

$ rvm get head


3. Устанавливаем / переустанавливаем ruby с применением патчей railsexpress

для версии Ruby 1.9.3-p362
$ rvm reinstall 1.9.3-p362 --patch railsexpress -n railsexpress -j 3
$ rvm list
$ rvm use ruby-1.9.3-p362-railsexpress --default

Если нужно всегда последнюю версию, то вместо p362 надо указать head,
но для последней версии патчи появляются с запазданием, это надо иметь ввиду.

4. Бонус

export RUBY_HEAP_MIN_SLOTS=1000000
export RUBY_HEAP_FREE_MIN=500000
export RUBY_HEAP_SLOTS_INCREMENT=1000000
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
export RUBY_GC_MALLOC_LIMIT=100000000


5. Меряем скорость

Скорость запуска рельс можно мерить так:
$ time bundle exec rake routes

В моем случае:
до
real 0m42.547s
user 0m36.502s
sys 0m2.248s

после
real 0m17.200s
user 0m15.089s
sys 0m1.072s


Здесь можно почитать дополнительную инфу по патчам https://github.com/skaes/rvm-patchsets
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 14

    +1
    Тоже самое для rbenv: gist.github.com/4381019
      +2
      Почему эти патчи прямиком не направятся к Matz?
      Ведь проще отправить pull request и чтобы они были сразу в ядре
        +1
        Это вопрос к Matz'у :) На сколько я помню эти патчи предлогались в ruby-core рассылке. Но он почему-то не захотел.
          +1
          Лучше всего это рассказывает как раз FunnyFalcon, Юра Соколов.
          Например был патч ускоряющий загрузку — у Юрия он был сразу с учетом узких мест но смотрелся сложновато, поэтому вначале смержили другой. Потом до неучтеных моментов добрались, и все доделали, а Юрин патч, который собственно сразу все и фиксил, пролетел.
          Мораль — мержат легко и просто легкие и простые патчи.

          Кстати вроде бы array queue уже вмержили в какую-то ветку.
          +2
          > Указываем RVM с какими параметрами надо компилить Ruby

          Для AMD лучше делать так

          rvm_configure_env=(CHOST="x86_64-pc-linux-gnu" CFLAGS="-march=k8 -O3 -pipe" CXXFLAGS="${CFLAGS}")
          


          -fomit-frame-pointer на AMD не работает.

          А вобще для каждого процессора лучше смотреть сюда — en.gentoo-wiki.com/wiki/Safe_Cflags
            0
            Померяйте у себя производительность с native и с k8, интересно же!
            Если ускорение будет существенным, я обязательно добавлю это в статью.

            В моем случае:
            -march=native
            

            real 0m17.200s user 0m15.089s sys 0m1.072s

            -march=corei7
            

            real 0m17.153s user 0m15.093s sys 0m1.076s

            -march=native — избавляет нас от некоторых сложностей с подборкой параметров и делает это хорошо.
            А раз так, то смысл перегружать статью лишней информацией?

              +1
              В приведенном случае упор был на отсутствие -fomit-frame-pointer и на то что из-за некоторых косяков в gcc, он не всегда способен самостоятельно опознать архитектуру используя native. Ну и плюс использование -O3 (что не у каждого заработает, по этому лучше смотреть Safe Flags)
              +1
              на AMD64 (x86_64) в смысле не работает? Я не вижу зависимости ABI от производителя процессора.

              Но вообще frame pointer в руби выключать не стоит в принципе. Минимальный оверхед на грани заметности, а дебажить скучнее становится в разы.
                0
                конкретно у меня просто не собирается. ошибку не помню, но не пашет. AMD Athlon(tm) 64 X2 Dual Core Processor 6000+. Ubuntu x64 12.10
              0
              где бы почитать описание что делает каждый патч? по указанной ссылке только
              Some of the patches are based on the work of others (some of them are included in ruby enterprise edition)

              ну и ссылки на те патчи, на основании которых сделаны «some of the patches».
              внутри *.patch тоже без комментов
                0
                Я думаю лучший вариант это читать патчи и пытаться понять что они делают :)

                Хотя по названиям большинство понять можно.
                0
                Если кто-то захочет дать инвайт funny falcon-у, патчи которого есть в этом сете, напишите, скину его почту.
                  0
                  Очень ценная заметка, благодарю!
                    0
                    Для недавно вышедшего свеженького ruby-1.9.3-p374:

                    $ rvm get head
                    $ rvm reinstall 1.9.3-p374 --patch railsexpress -n railsexpress -j 3
                    $ rvm list
                    $ rvm use ruby-1.9.3-p374-railsexpress --default
                    

                    Only users with full accounts can post comments. Log in, please.