Скачать презентацию Rubinius Ruby написанный на Ruby Самсонов Иван Оверсан-Скалакси Скачать презентацию Rubinius Ruby написанный на Ruby Самсонов Иван Оверсан-Скалакси

33fd42e58d34f65d5285e6e488ec30aa.ppt

  • Количество слайдов: 37

Rubinius: Ruby, написанный на Ruby Самсонов Иван, Оверсан-Скалакси Rubinius: Ruby, написанный на Ruby Самсонов Иван, Оверсан-Скалакси

Летом 2006 года, где-то в США А не написать ли мне свой Ruby с Летом 2006 года, где-то в США А не написать ли мне свой Ruby с блекджеком и шлюхами?

Что такое Rubinius? Evan Phoenix Bytecode JIT VM Ruby Melbourne Engine Yard LLVM Что такое Rubinius? Evan Phoenix Bytecode JIT VM Ruby Melbourne Engine Yard LLVM

Rubinius это: Программа, которая транслирует код программы на Ruby, например: puts 123 в эффективный Rubinius это: Программа, которая транслирует код программы на Ruby, например: puts 123 в эффективный машинный код с последующим его исполнением: push %rbp; mov %rsp, %rbp; push %rbx; subq $0 x 98, %rsp; cmp $0 x 0, 0 x 10(%rcx); call 0 xfffff 472010; jmp 0 x 9 c;

Rubinius это: Имплементация языка программирования Ruby Rubinius это: Имплементация языка программирования Ruby

Нормально ли, что Rubinius написан на Ruby? Да! Ведь, например: • изрядная часть языка Нормально ли, что Rubinius написан на Ruby? Да! Ведь, например: • изрядная часть языка Java написана на нём самом; • Где не получается использовать Ruby, используется C++;

Нормально ли, что Rubinius написан на Ruby? static VALUE rb_ary_collect(ary) VALUE ary; { long Нормально ли, что Rubinius написан на Ruby? static VALUE rb_ary_collect(ary) VALUE ary; { long i; VALUE collect; if (!rb_block_given_p()) { return rb_ary_new 4(RARRAY(ary)->len, RARRAY(ary)->ptr); } collect = rb_ary_new 2(RARRAY(ary)->len); for (i = 0; i < RARRAY(ary)->len; i++) { rb_ary_push(collect, rb_yield(RARRAY(ary)->ptr[i])); } return collect; }

Нормально ли, что Rubinius написан на Ruby? module Enumerable def collect if block_given? ary Нормально ли, что Rubinius написан на Ruby? module Enumerable def collect if block_given? ary = [] each { |o| ary << yield(o) } ary else to_a end alias_method : map, : collect end

Почему Rubinius? Почему Rubinius?

Почему Ruby? Почему Ruby?

Потому, что Ruby: • Динамичный; • Человечный; • Удобный. Потому, что Ruby: • Динамичный; • Человечный; • Удобный.

. . . но при этом Ruby медленный . . . но при этом Ruby медленный

Одна из целей проекта Rubinius - сделать Ruby быстрым Одна из целей проекта Rubinius - сделать Ruby быстрым

История Rubinius Старт проекта Команда расширяется Engine Yard нанимает Эвана Запуск Rails VM на История Rubinius Старт проекта Команда расширяется Engine Yard нанимает Эвана Запуск Rails VM на C++ JIT stackfull бренч мержится в master Повторный запуск Rails

Преимущества Rubinius • • • Компактное быстрое ядро VM; сборщик мусора, основанный на поколениях; Преимущества Rubinius • • • Компактное быстрое ядро VM; сборщик мусора, основанный на поколениях; поддержка расширений языка C; большая часть кода реализована на Ruby; JIT; Ruby. Spec;

Сборщик мусора • Перемещающая стратегия; • Immix mark-region сборщик; Сборщик мусора • Перемещающая стратегия; • Immix mark-region сборщик;

Стадии компилятора байткода. rb файл Node дерево sexps bytecode AST Стадии компилятора байткода. rb файл Node дерево sexps bytecode AST

Результат компилятора байткода def foo(a, b) a + b end 0000: push_local 0 # Результат компилятора байткода 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 машинный код Стадии JIT bytecode LLVM IR машинный код

Входящий Ruby-код для JIT class Flower def bloom(*a) a end Входящий Ruby-код для JIT class Flower def bloom(*a) a end

JIT – результат преобразования 0 x 2280010 sub $0 xc, %esp 0 x 2280013 JIT – результат преобразования 0 x 2280010 sub $0 xc, %esp 0 x 2280013 mov 0 x 1 c(%esp), %eax 0 x 2280017 mov %eax, 0 x 4(%esp) 0 x 228001 b mov 0 x 10(%esp), %eax 0 x 228001 f mov %eax, (%esp) 0 x 2280022 mov $0 x 0, 0 x 8(%esp) 0 x 228002 a call 0 xfffffde 9 d 640 ; 0 x 11 d 650 rbx_construct_splat 0 x 228002 f add $0 xc, %esp 0 x 2280032 ret

Дальнейшая оптимизация: Method Inlining Дальнейшая оптимизация: Method Inlining

Примитивы class Fixnum : public Integer { public: // Ruby. primitive! : fixnum_or Integer* Примитивы 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 Backtrace puts "123" + 1 ruby z. rb: 1: in `+': can't convert Fixnum into String (Type. Error) from z. rb: 1 bin/rbx z. rb Coercion error: 1. to_str => String failed (Type. Error) Backtrace: Type. coerce_to Kernel(String)#String. Value String#+ main. __script__ Rubinius: : Code. Loader#load_script Rubinius: : Code. Loader. load_script Rubinius: : Loader#main Rubinius: : Loader. main Object#__script__ at at at kernel/common/type. rb: 22 kernel/common/kernel. rb: 112 kernel/common/string. rb: 78 z. rb: 1 kernel/delta/codeloader. rb: 65 kernel/delta/codeloader. rb: 88 kernel/loader. rb: 435 kernel/loader. rb: 526 kernel/loader. rb: 552 kernel/loader. rb: 564

Плагины компилятора # -*- array_zen -*q = +[ x**2 , x. in([1, 2, 3])] Плагины компилятора # -*- array_zen -*q = +[ x**2 , x. in([1, 2, 3])] p q # => [1, 4, 9]

Тестирование языка программирования • Mspec • Ruby. Spec describe Тестирование языка программирования • Mspec • Ruby. Spec 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; Небольшое сообщество; Непригоден для продакшена; Несовместимость Проблемы с Rubinius: • • Отсутствие поддержки Windows; Небольшое сообщество; Непригоден для продакшена; Несовместимость с некоторыми гемами (C, Ruby); • Отсутствие актуальной документации;

Пример «багов» : x=0 loop do puts x > -123 # => true end Пример «багов» : x=0 loop do puts x > -123 # => true end

Планы по развитию: • • JIT Debugger 1. 9 Windows Планы по развитию: • • JIT Debugger 1. 9 Windows

Бенчмарки rubinius 1. 0. 0 (1. 8. 7 e 6 c 32 afd 2010 Бенчмарки rubinius 1. 0. 0 (1. 8. 7 e 6 c 32 afd 2010 -05 -14 JI) ruby 1. 9. 2 dev (2010 -04 -14 trunk 27342) ruby 1. 8. 7 (2010 -01 -10 patchlevel 249) jruby 1. 6. 0. dev (ruby 1. 8. 7 patchlevel 249) (2010 -04 -14 7 cb 1298) Mac. Ruby version 0. 6 (ruby 1. 9. 0)

Рекурсия def fib(n) if (n < 2) n else fib(n-1) + fib(n-2) end Рекурсия 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 Хеш функция def foo hash = {} 100. times {|i| hash[i] = 0} end

Хеш функция Хеш функция

Простое Rails приложение • Rails 2. 3. 5 • WEBrick • ab -c 5 Простое Rails приложение • Rails 2. 3. 5 • WEBrick • ab -c 5 -n 1000 http: //127. 0. 0. 1: 3000/ • authlogick example

Простое Rails приложение Простое Rails приложение

А ты стал контрибутором Rubinius? А ты стал контрибутором Rubinius?