1 / 37

Rubinius: Ruby, написанный на Ruby

Самсонов Иван, Оверсан-Скалакси. Rubinius: Ruby, написанный на Ruby. Летом 2006 года, где-то в США. А не написать ли мне свой Ruby с блекджеком и шлюхами?. Что такое Rubinius?. JIT. VM. Evan Phoenix. Ruby. Bytecode. Engine Yard. LLVM. Melbourne. Rubinius это:.

cosima
Télécharger la présentation

Rubinius: Ruby, написанный на Ruby

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

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

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

  4. Rubinius это: Программа, которая транслирует код программы на Ruby, например: puts 123 в эффективный машинный код с последующим его исполнением: push %rbp; mov %rsp, %rbp; push %rbx; subq $0x98, %rsp; cmp $0x0, 0x10(%rcx); call 0xffffffffff472010; jmp 0x9c;

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

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

  7. Нормально ли, что 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 < RARRAY(ary)->len; i++) { rb_ary_push(collect, rb_yield(RARRAY(ary)->ptr[i])); } return collect; }

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

  9. Почему Rubinius?

  10. Почему Ruby?

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

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

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

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

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

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

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

  18. Результат компилятора байткода def foo(a,b)‏ a + b end 0000:  push_local                 0    # a 0002:  push_local                 1    # b 0004:  meta_send_op_plus          :+ 0006:  ret

  19. Стадии JIT bytecode машинный код LLVM IR

  20. Входящий Ruby-код для JIT class Flower defbloom(*a)‏ a end end

  21. JIT – результат преобразования 0x2280010 sub $0xc, %esp 0x2280013 mov 0x1c(%esp), %eax 0x2280017 mov %eax, 0x4(%esp)‏ 0x228001b mov 0x10(%esp), %eax 0x228001f mov %eax, (%esp)‏ 0x2280022 mov $0x0, 0x8(%esp)‏ 0x228002a call 0xfffffffffde9d640 ; 0x11d650 rbx_construct_splat 0x228002f add $0xc, %esp 0x2280032 ret

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

  23. Примитивы 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 end

  24. Backtrace puts "123"+ 1 ruby z.rb z.rb:1:in `+': can't convert Fixnum into String (TypeError)‏ from z.rb: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

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

  26. Тестирование языка программирования • 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 end

  27. Проблемы с Rubinius: • Отсутствие поддержки Windows; • Небольшое сообщество; • Непригоден для продакшена; • Несовместимость с некоторыми гемами (C, Ruby)‏; • Отсутствие актуальной документации;

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

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

  30. Бенчмарки rubinius 1.0.0 (1.8.7 e6c32afd 2010-05-14 JI)‏ ruby 1.9.2dev (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 7cb1298)‏ MacRuby version 0.6 (ruby 1.9.0)‏

  31. Рекурсия deffib(n)‏ if (n < 2)‏ n else fib(n-1) + fib(n-2)‏ end end

  32. Рекурсия

  33. Хеш функция deffoo hash = {} 100.times {|i| hash[i] = 0} end

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

  35. Простое Rails приложение • Rails 2.3.5 • WEBrick • ab -c 5 -n 1000 http://127.0.0.1:3000/ • authlogick example

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

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

More Related