Cайт веб-разработчика, программиста Ruby on Rails ESV Corp. Екатеринбург, Москва, Санкт-Петербург, Первоуральск

Админка на Ruby on Rails

Оптимизация критичных в скорости алгоритмов в Ruby с помощью V8

Для критичных в скорости алгоритмов в Ruby возможно использование движка V8 JavaScript. В процессе проведения простейших тестов производительности, скорости выполнения программ (и более сложных, где сравнивалась уже производительность Ruby и PHP), и обсуждения с людьми выяснилось, что Ruby проигрывает в скорости JavaScript, который использует движок V8, что не удивительно, если верить Википедии: "Компиляция исходного кода JavaScript непосредственно в собственный машинный код, минуя стадию промежуточного байт-кода.". Фактически с движком V8 JavaScript переходит в разряд компилируемых языков, и сравнение с Ruby становится уже несправедливым, но тем не менее.

Но самое замечательное - в Ruby запросто можно использовать V8, подключив соответствующий gem - therubyracer, в Ruby on Rails он вообще требуется для работы. С помощью этого gem-а производится интеграция кода Ruby с кодом JavaScript.

Вот пример теста Фибоначчи и наглядные результаты выполнения:

require "benchmark"
require "v8"

def fib(n)
  return n if n <= 1
  fib(n - 1) + fib(n - 2)
end

Benchmark.bm do | make |

  i = 0

  6.times do

    make.report { puts fib(30 + i) }

    i += 1

  end

end


ctx = V8::Context.new

fib_js = ctx.eval <<-JS

  function Fib() {

    this.fib = function(n) {

      if (n <= 1) {
        return n;
      }

      return (this.fib(n - 1) + this.fib(n - 2));
    };
  }

  new Fib();

JS

puts 'Using V8:'

Benchmark.bm do | make |

  i = 0

  6.times do

    make.report { puts fib_js.fib(30 + i) }

    i += 1

  end

end

 

Результаты:

       user     system      total        real
 832040
  0.250000   0.000000   0.250000 (  0.248631)
 1346269
  0.400000   0.000000   0.400000 (  0.400701)
 2178309
  0.640000   0.000000   0.640000 (  0.639987)
 3524578
  1.030000   0.000000   1.030000 (  1.029717)
 5702887
  1.670000   0.000000   1.670000 (  1.669645)
 9227465
  2.700000   0.000000   2.700000 (  2.700381)

Using V8:
       user     system      total        real
 832040
  0.030000   0.000000   0.030000 (  0.034632)
 1346269
  0.060000   0.000000   0.060000 (  0.053876)
 2178309
  0.090000   0.000000   0.090000 (  0.086107)
 3524578
  0.130000   0.000000   0.130000 (  0.137856)
 5702887
  0.220000   0.000000   0.220000 (  0.216403)
 9227465
  0.360000   0.000000   0.360000 (  0.353677)

 

Как можно видеть, алгоритм выполняется в ~7-8 раз быстрее. Хотя мне лично всегда было достаточно той скорости выполнения программ, которую предоставляет Ruby, никогда не сталкивался с тем, что Ruby где-то тормозит. Но на этом примере видно, что если кому-о недостаточно производительности, то есть способы оптимизации "узких мест" в программе.