Rubinius: Ruby, написанный на Ruby Самсонов Иван, Оверсан-Скалакси
Летом 2006 года, где-то в США А не написать ли мне свой Ruby с блекджеком и шлюхами?
Что такое Rubinius? Ruby LLVM JIT Engine Yard Evan Phoenix VM Melbourne Bytecode
Программа, которая транслирует код программы на Ruby, например: puts 123 в эффективный машинный код с последующим его исполнением: push %rbp; mov %rsp, %rbp; push %rbx; subq $0x98, %rsp; cmp $0x0, 0x10(%rcx); call 0xffffffffff472010; jmp 0x9c; Rubinius это:
Имплементация языка программирования Ruby Rubinius это:
Нормально ли, что Rubinius написан на Ruby? Да! Ведь, например: изрядная часть языка Java написана на нём самом; Где не получается использовать Ruby, используется C++;
Нормально ли, что Rubinius написан на Ruby? static VALUE rb_ary_collect(ary) VALUE ary; { long i; VALUE collect; if (!rb_block_given_p()) { return rb_ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr); } collect = rb_ary_new2(RARRAY(ary)->len); for (i = 0; i len; i++) { rb_ary_push(collect, rb_yield(RARRAY(ary)->ptr[i])); } return collect; }
Нормально ли, что Rubinius написан на Ruby? module Enumerable def collect if block_given? ary = [] each { |o| ary
Почему Rubinius?
Почему Ruby?
Потому, что Ruby: Динамичный; Человечный; Удобный.
...но при этом Ruby медленный
Одна из целей проекта Rubinius - сделать Ruby быстрым
История Rubinius Старт проекта Engine Yard нанимает Эвана Команда расширяется Запуск Rails VM на C++ stackfull бренч мержится в master JIT Повторный запуск Rails
Преимущества Rubinius Компактное быстрое ядро VM; сборщик мусора, основанный на поколениях; поддержка расширений языка C; большая часть кода реализована на Ruby; JIT; RubySpec;
Сборщик мусора Перемещающая стратегия; Immix mark-region сборщик;
Стадии компилятора байткода.rb файл Node дерево sexps AST bytecode
Результат компилятора байткода def foo(a,b) a + b end 0000: push_local 0 # a 0002: push_local 1 # b 0004: meta_send_op_plus :+ 0006: ret
Стадии JIT bytecode LLVM IR машинный код
Входящий Ruby-код для JIT class Flower def bloom(*a) a end
JIT – результат преобразования 0x sub $0xc, %esp 0x mov 0x1c(%esp), %eax 0x mov %eax, 0x4(%esp) 0x228001b mov 0x10(%esp), %eax 0x228001f mov %eax, (%esp) 0x mov $0x0, 0x8(%esp) 0x228002a call 0xfffffffffde9d640 ; 0x11d650 rbx_construct_splat 0x228002f add $0xc, %esp 0x ret
Дальнейшая оптимизация: Method Inlining
Примитивы class Fixnum : public Integer { public: // Ruby.primitive! :fixnum_or Integer* bit_or(STATE, Fixnum* other); }; class Fixnum < Integer def |(o) Ruby.primitive :fixnum_or end
Backtrace puts "123" + 1 bin/rbx z.rb Coercion error: 1.to_str => String failed (TypeError) Backtrace: Type.coerce_to at kernel/common/type.rb:22 Kernel(String)#StringValue at kernel/common/kernel.rb:112 String#+ at kernel/common/string.rb:78 main.__script__ at z.rb:1 Rubinius::CodeLoader#load_script at kernel/delta/codeloader.rb:65 Rubinius::CodeLoader.load_script at kernel/delta/codeloader.rb:88 Rubinius::Loader#script at kernel/loader.rb:435 Rubinius::Loader#main at kernel/loader.rb:526 Rubinius::Loader.main at kernel/loader.rb:552 Object#__script__ at kernel/loader.rb:564 ruby z.rb z.rb:1:in `+': can't convert Fixnum into String (TypeError) from z.rb:1
Плагины компилятора # -*- array_zen -*- q = +[ x**2, x.in([1,2,3])] p q # => [1, 4, 9]
Тестирование языка программирования Mspec RubySpec describe "Array#shift" do it "removes and returns the first element" do a = [5, 1, 1, 5, 4] a.shift.should == 5 end it "returns nil when the array is empty" do [].shift.should == nil end
Проблемы с Rubinius: Отсутствие поддержки Windows; Небольшое сообщество; Непригоден для продакшена; Несовместимость с некоторыми гемами (C, Ruby) ; Отсутствие актуальной документации;
Пример «багов»: x = 0 loop do puts x > -123 # => true end
Планы по развитию: JIT Debugger 1.9 Windows
Бенчмарки rubinius (1.8.7 e6c32afd JI) ruby 1.9.2dev ( trunk 27342) ruby ( patchlevel 249) jruby dev (ruby patchlevel 249) ( cb1298) MacRuby version 0.6 (ruby 1.9.0)
Рекурсия def fib(n) if (n < 2) n else fib(n-1) + fib(n-2) end
Рекурсия
Хеш функция def foo hash = {} 100.times {|i| hash[i] = 0} end
Хеш функция
Простое Rails приложение Rails WEBrick ab -c 5 -n authlogick example
Простое Rails приложение
А ты стал контрибутором Rubinius?