Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pre-evaluation in Ruby

Pre-evaluation in Ruby

Ruby is historically difficult to optimize due to features that improve flexibility and productivity at the cost of performance. Techniques like Ruby's new JIT compiler and deoptimization code help, but still are limited by techniques like monkey-patching and binding inspection.

Pre-evaluation is another optimization technique that works based on user-defined contracts and assumptions. Users can opt in to optimizations by limiting their use of Ruby's features and thereby allowing further compiler work.

In this talk we'll look at how pre-evaluation works, and what benefits it enables.

Kevin Newton

April 30, 2019
Tweet

More Decks by Kevin Newton

Other Decks in Programming

Transcript

  1. Pre-evaluation
    in Ruby

    View full-size slide

  2. Kevin Deisz
    @kddeisz

    View full-size slide

  3. Lexical Analysis
    Compilers

    View full-size slide

  4. Lexical Analysis
    Semantic Analysis
    Compilers

    View full-size slide

  5. Lexical Analysis
    Semantic Analysis
    Instruction Generation
    Compilers

    View full-size slide

  6. Lexical Analysis
    Semantic Analysis
    Instruction Generation
    Optimization
    Compilers

    View full-size slide

  7. Lexical Analysis
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  8. Matz is nice so we are nice.
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  9. Matz is nice so
    we are nice .
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  10. is nice so
    we are nice .
    Matz
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  11. is nice so
    we are nice .
    Matz
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  12. Matz is nice
    we are nice .
    so
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  13. Matz is nice so
    we are nice .
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  14. Matz is nice so
    we are nice .
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  15. Matz is nice so
    we are .
    nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  16. Matz is nice so
    we are nice .
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  17. Matz is nice so
    we are nice .
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  18. Semantic Analysis
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  19. Matz is nice so
    we are nice .
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  20. is nice are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  21. Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  22. verb-phrase : VERB ADJECTIVE
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  23. is nice are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  24. is nice
    verb
    phrase
    verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  25. Matz
    is nice
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  26. verb-phrase : VERB ADJECTIVE
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  27. subject-phrase : NOUN verb-phrase
    verb-phrase : VERB ADJECTIVE
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  28. Matz
    is nice
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  29. Matz
    is nice
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  30. Matz
    is nice
    so
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  31. subject-phrase : NOUN verb-phrase
    verb-phrase : VERB ADJECTIVE
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  32. subordinating-conjunction :

    subject-phrase CONJUNCTION subject-phrase
    subject-phrase : NOUN verb-phrase
    verb-phrase : VERB ADJECTIVE
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  33. Matz
    is nice
    so
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  34. Matz
    is nice
    so
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  35. Matz
    is nice
    so
    .
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  36. subordinating-conjunction :

    subject-phrase CONJUNCTION subject-phrase
    subject-phrase : NOUN verb-phrase
    verb-phrase : VERB ADJECTIVE
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  37. sentence : subordinating-conjunction PERIOD
    subordinating-conjunction :

    subject-phrase CONJUNCTION subject-phrase
    subject-phrase : NOUN verb-phrase
    verb-phrase : VERB ADJECTIVE
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  38. Matz
    is nice
    so
    .
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  39. Matz
    is nice
    so
    .
    sentence
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  40. sentence : subordinating-conjunction PERIOD
    subordinating-conjunction :

    subject-phrase CONJUNCTION subject-phrase
    subject-phrase : NOUN verb-phrase
    verb-phrase : VERB ADJECTIVE
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  41. class Calcp
    prechigh
    nonassoc UMINUS
    left '*' '/'
    left '+' '-'
    preclow
    rule
    target: exp
    | /* none */ { result = 0 }
    exp: exp '+' exp { result += val[2] }
    | exp '-' exp { result -= val[2] }
    | exp '*' exp { result *= val[2] }
    | exp '/' exp { result /= val[2] }
    | '(' exp ')' { result = val[1] }
    | '-' NUMBER =UMINUS { result = -val[1] }
    | NUMBER
    end
    https://github.com/tenderlove/racc/blob/master/sample/calc.y
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  42. | arg '+' arg
    {
    $$ = call_bin_op(p, $1, '+', $3, &@2, &@$);
    }
    | arg '-' arg
    {
    $$ = call_bin_op(p, $1, '-', $3, &@2, &@$);
    }
    | arg '*' arg
    {
    $$ = call_bin_op(p, $1, '*', $3, &@2, &@$);
    }
    | arg '/' arg
    {
    $$ = call_bin_op(p, $1, '/', $3, &@2, &@$);
    }
    https://github.com/ruby/ruby/blob/trunk/parse.y
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  43. sentence : subordinating-conjunction PERIOD
    subordinating-conjunction :

    subject-phrase CONJUNCTION subject-phrase
    subject-phrase : NOUN verb-phrase
    verb-phrase : VERB ADJECTIVE
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  44. Instruction
    Generation
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  45. Matz
    is nice
    so
    .
    sentence
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  46. is nice
    verb
    phrase
    verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  47. verb-phrase : VERB ADJECTIVE

    Instructions
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  48. verb-phrase : VERB ADJECTIVE

    push-attr($2)
    Instructions
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  49. is nice
    verb
    phrase
    verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  50. Matz
    is nice
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  51. verb-phrase : VERB ADJECTIVE

    push-attr($2)
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  52. subject-phrase : NOUN verb-phrase

    verb-phrase : VERB ADJECTIVE

    push-attr($2)
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  53. subject-phrase : NOUN verb-phrase

    save-attr($1, pop-attr)
    verb-phrase : VERB ADJECTIVE

    push-attr($2)
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  54. Matz
    is nice
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  55. Matz
    is nice
    so
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  56. subject-phrase : NOUN verb-phrase

    save-attr($1, pop-attr)
    verb-phrase : VERB ADJECTIVE

    push-attr($2)
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  57. subordinating-conjunction :

    subject-phrase CONJUNCTION subject-phrase

    subject-phrase : NOUN verb-phrase

    save-attr($1, pop-attr)
    verb-phrase : VERB ADJECTIVE

    push-attr($2)
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  58. subordinating-conjunction :

    subject-phrase CONJUNCTION subject-phrase

    cond-skip($1, $2)
    subject-phrase : NOUN verb-phrase

    save-attr($1, pop-attr)
    verb-phrase : VERB ADJECTIVE

    push-attr($2)
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  59. Matz
    is nice
    so
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  60. Matz
    is nice
    so
    .
    sentence
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  61. subordinating-conjunction :

    subject-phrase CONJUNCTION subject-phrase

    cond-skip($1, $2)
    subject-phrase : NOUN verb-phrase

    save-attr($1, pop-attr)
    verb-phrase : VERB ADJECTIVE

    push-attr($2)
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  62. sentence : subordinating-conjunction PERIOD

    subordinating-conjunction :

    subject-phrase CONJUNCTION subject-phrase

    cond-skip($1, $2)
    subject-phrase : NOUN verb-phrase

    save-attr($1, pop-attr)
    verb-phrase : VERB ADJECTIVE

    push-attr($2)
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  63. sentence : subordinating-conjunction PERIOD

    trace($1)
    subordinating-conjunction :

    subject-phrase CONJUNCTION subject-phrase

    cond-skip($1, $2)
    subject-phrase : NOUN verb-phrase

    save-attr($1, pop-attr)
    verb-phrase : VERB ADJECTIVE

    push-attr($2)
    Grammar
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  64. Matz
    is nice
    so
    .
    sentence
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  65. Matz
    is nice
    so
    .
    sentence
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    trace(5)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  66. Matz
    is nice
    so
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    trace(5)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  67. Matz
    is nice
    so
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    verb
    phrase
    we verb
    phrase
    are nice
    trace(5)
    push-attr(“nice”)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  68. Matz
    so
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    we verb
    phrase
    are nice
    trace(5)
    push-attr(“nice”)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  69. Matz
    so
    subord.
    conjunction
    subject
    phrase
    subject
    phrase
    we verb
    phrase
    are nice
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  70. so
    subord.
    conjunction
    subject
    phrase
    we verb
    phrase
    are nice
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  71. so
    subord.
    conjunction
    subject
    phrase
    we verb
    phrase
    are nice
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  72. subject
    phrase
    we verb
    phrase
    are nice
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  73. subject
    phrase
    we verb
    phrase
    are nice
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    push-attr(“nice”)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  74. subject
    phrase
    we
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    push-attr(“nice”)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  75. subject
    phrase
    we
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    push-attr(“nice”)
    trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    push-attr(“nice”)
    save-attr(:we, pop-attr)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  76. trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    push-attr(“nice”)
    save-attr(:we, pop-attr)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  77. trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    push-attr(“nice”)
    save-attr(:we, pop-attr)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  78. Optimization
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  79. trace(5)
    push-attr(“nice”)
    save-attr(:Matz, pop-attr)
    cond-skip(2)
    push-attr(“nice”)
    save-attr(:we, pop-attr)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  80. trace(5)
    push-attr(“blue”)
    save-attr(:Sky, pop-attr)
    cond-skip(2)
    push-attr(“nice”)
    save-attr(:we, pop-attr)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  81. trace(5)
    push-attr(“blue”)
    save-attr(:Sky, pop-attr)
    cond-skip(2)
    push-attr(“nice”)
    save-attr(:we, pop-attr)
    constant
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  82. trace(5)
    push-attr(“nice”)
    save-attr(:we, pop-attr)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  83. trace(5)
    push-attr(“nice”)
    save-attr(:we, pop-attr)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  84. We are nice.
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  85. Let’s look at Ruby
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization

    View full-size slide

  86. if 5 + 3 == 8
    puts 'Hello, world!'
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  87. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  88. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 putobject 5 ( 2)
    0003 putobject 3
    0005 opt_plus , 0008 putobject 8
    0010 opt_eq , 0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)

    View full-size slide

  89. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 putobject 5 ( 2)
    0003 putobject 3
    0005 opt_plus , 0008 putobject 8
    0010 opt_eq , 0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  90. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 putobject 5 ( 2)
    0003 putobject 3
    0005 opt_plus , 0008 putobject 8
    0010 opt_eq , 0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  91. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 putobject 5 ( 2)
    0003 putobject 3
    0005 opt_plus , 0008 putobject 8
    0010 opt_eq , 0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  92. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 putobject 8 ( 2)
    0008 putobject 8
    0010 opt_eq , 0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  93. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 putobject 8 ( 2)
    0008 putobject 8
    0010 opt_eq , 0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  94. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 putobject 8 ( 2)
    0008 putobject 8
    0010 opt_eq , 0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  95. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 putobject true ( 2)
    0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  96. if 5 + 3 == 8
    puts 'Hello, world!'
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  97. if true
    puts 'Hello, world!'
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  98. Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  99. require 'net/http'; require 'uri'; require 'nokogiri'
    url = 'https://twitter.com/kddeisz/status/1105570552465575937'
    body = Net::HTTP.get_response(URI.parse(url)).body
    node = Nokogiri::HTML(resp).at_css('.tweet-text')
    eval(node.text)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  100. require 'net/http'; require 'uri'; require 'nokogiri'
    url = 'https://twitter.com/kddeisz/status/1105570552465575937'
    body = Net::HTTP.get_response(URI.parse(url)).body
    node = Nokogiri::HTML(resp).at_css('.tweet-text')
    eval(node.text)
    5 + 3 # => 2
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  101. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 putobject 5 ( 2)
    0003 putobject 3
    0005 opt_plus , 0008 putobject 8
    0010 opt_eq , 0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)

    View full-size slide

  102. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 putobject 5 ( 2)
    0003 putobject 3
    0005 opt_plus , 0008 putobject 8
    0010 opt_eq , 0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)

    View full-size slide

  103. code = -> {
    if 5 + 3 == 8
    puts 'Hello, world!'
    end
    }
    puts RubyVM::InstructionSequence.disasm(code)
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation
    == disasm: # (catch: FALSE)
    == catch table
    | catch type: redo st: 0001 ed: 0023 sp: 0000 cont: 0001
    | catch type: next st: 0001 ed: 0023 sp: 0000 cont: 0023
    |------------------------------------------------------------------------
    0000 nop ( 1)
    0001 opt_plus_deopt 8 ( 2)
    0010 opt_eq , 0013 branchunless 22
    0015 putself ( 3)
    0016 putstring "Hello, world!"
    0018 opt_send_without_block 0021 leave ( 5)
    0022 putnil ( 3)
    0023 nop
    0024 leave ( 5)

    View full-size slide

  104. WHY WOULD YOU EVER DO THIS!!
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  105. Ripper.sexp_raw('5 + 3')
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  106. Ripper.sexp_raw('5 + 3')
    [:program,
    [:stmts_add,
    [:stmts_new],
    [:binary, [:@int, "5", [1, 0]], :+, [:@int, "3", [1, 4]]]]]
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  107. module Preval
    class Parser < Ripper::SexpBuilder
    def self.parse(source)
    new(source).parse
    end
    private
    SCANNER_EVENTS.each do |event|
    define_method(:"on_#{event}") do |token|
    Node.new(:"@#{event}", token, true)
    end
    end
    PARSER_EVENTS.each do |event|
    define_method(:"on_#{event}") do |*args|
    Node.new(event, args)
    end
    end
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  108. module Preval
    class Parser < Ripper::SexpBuilder
    def self.parse(source)
    new(source).parse
    end
    private
    SCANNER_EVENTS.each do |event|
    define_method(:"on_#{event}") do |token|
    Node.new(:"@#{event}", token, true)
    end
    end
    PARSER_EVENTS.each do |event|
    define_method(:"on_#{event}") do |*args|
    Node.new(event, args)
    end
    end
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  109. module Preval
    class Parser < Ripper::SexpBuilder
    def self.parse(source)
    new(source).parse
    end
    private
    SCANNER_EVENTS.each do |event|
    define_method(:"on_#{event}") do |token|
    Node.new(:"@#{event}", token, true)
    end
    end
    PARSER_EVENTS.each do |event|
    define_method(:"on_#{event}") do |*args|
    Node.new(event, args)
    end
    end
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  110. module Preval
    class Parser < Ripper::SexpBuilder
    def self.parse(source)
    new(source).parse
    end
    private
    SCANNER_EVENTS.each do |event|
    define_method(:"on_#{event}") do |token|
    Node.new(:"@#{event}", token, true)
    end
    end
    PARSER_EVENTS.each do |event|
    define_method(:"on_#{event}") do |*args|
    Node.new(event, args)
    end
    end
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  111. module Preval
    class Node
    include Format
    attr_reader :type, :body, :literal
    def initialize(type, body, literal = false)
    @type = type
    @body = body
    @literal = literal
    end
    def to_source
    return body if literal
    public_send(:"to_#{type}")
    end
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  112. module Preval
    class Node
    include Format
    attr_reader :type, :body, :literal
    def initialize(type, body, literal = false)
    @type = type
    @body = body
    @literal = literal
    end
    def to_source
    return body if literal
    public_send(:"to_#{type}")
    end
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  113. module Preval
    module Format
    def self.to(type, &block)
    define_method(:"to_#{type}", &block)
    end
    to(:alias) { "alias #{source(0)} #{source(1)}" }
    to(:aref) { body[1] ? "#{source(0)}[#{source(1)}]" : "#{source(0)}[]" }
    to(:aref_field) { "#{source(0)}[#{source(1)}]" }
    to(:arg_paren) { body[0].nil? ? '' : "(#{source(0)})" }
    to(:args_add) { starts_with?(:args_new) ? source(1) : join(', ') }
    to(:args_add_block) do
    args, block = body
    parts = args.is?(:args_new) ? [] : [args.to_source]
    parts << "#{parts.any? ? ', ' : ''}{block.to_source}" if block
    parts.join
    end
    to(:args_add_star) { starts_with?(:args_new) ? "*#{source(1)}" : "#{source(0)}, *#{source(1)}" }
    to(:args_new) { '' }
    to(:assign) { "#{source(0)} = #{source(1)}" }
    to(:array) { body[0].nil? ? '[]' : "#{starts_with?(:args_add) ? '[' : ''}#{source(0)}]" }
    to(:assoc_new) { starts_with?(:@label) ? join(' ') : join(' => ') }
    to(:assoc_splat) { "**#{source(0)}" }
    to(:assoclist_from_args) { body[0].map(&:to_source).join(', ') }
    to(:bare_assoc_hash) { body[0].map(&:to_source).join(', ') }
    to(:begin) { "begin\n#{join("\n")}\nend" }
    to(:BEGIN) { "BEGIN {\n#{source(0)}\n}"}
    to(:binary) { "#{source(0)} #{body[1]} #{source(2)}" }
    to(:blockarg) { "{source(0)}" }
    to(:block_var) { "|#{source(0)}|" }
    to(:bodystmt) do
    source(0).tap do |code|
    code << "\n#{source(1)}" if body[1]
    if body[2]
    stmts = body[2].is?(:else) ? body[2].body[0] : body[2]
    code << "\nelse\n#{stmts.to_source}"
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  114. to(:string_literal) do
    content =
    source(0).map! do |part|
    part.start_with?('#{') ? part : part.gsub(/([^\\])"/) { "#{$1}\\\"" }
    end
    "\"#{content.join}\""
    end
    to(:super) { "super#{starts_with?(:arg_paren) ? '' : ' '}#{source(0)}" }
    to(:symbol) { ":#{source(0)}" }
    to(:symbol_literal) { source(0) }
    to(:symbols_add) { join(starts_with?(:symbols_new) ? '' : ' ') }
    to(:symbols_new) { '%I[' }
    to(:top_const_field) { "::#{source(0)}" }
    to(:top_const_ref) { "::#{source(0)}" }
    to(:unary) { "#{body[0][0]}#{source(1)}" }
    to(:undef) { "undef #{body[0][0].to_source}" }
    to(:unless) { "unless #{source(0)}\n#{source(1)}\n#{body[2] ? "#{source(2)}\n" : ''}end" }
    to(:unless_mod) { "#{source(1)} unless #{source(0)}" }
    to(:until) { "until #{source(0)}\n#{source(1)}\nend" }
    to(:until_mod) { "#{source(1)} until #{source(0)}" }
    to(:var_alias) { "alias #{source(0)} #{source(1)}" }
    to(:var_field) { join }
    to(:var_ref) { source(0) }
    to(:vcall) { join }
    to(:void_stmt) { '' }
    to(:when) { "when #{source(0)}\n#{source(1)}#{body[2] ? "\n#{source(2)}" : ''}" }
    to(:while) { "while #{source(0)}\n#{source(1)}\nend" }
    to(:while_mod) { "#{source(1)} while #{source(0)}" }
    to(:word_add) { join }
    to(:word_new) { '' }
    to(:words_add) { join(starts_with?(:words_new) ? '' : ' ') }
    to(:words_new) { '%W[' }
    to(:xstring_add) { join }
    to(:xstring_new) { '' }
    to(:xstring_literal) { "%x[#{source(0)}]" }
    to(:yield) { "yield#{starts_with?(:paren) ? '' : ' '}#{join}" }
    to(:yield0) { 'yield' }
    to(:zsuper) { 'super' }
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  115. module Preval
    class << self
    attr_reader :visitors
    def enable_all!
    Visitors::Arithmetic.enable!
    Visitors::AttrAccessor.enable!
    Visitors::Fasterer.enable!
    Visitors::Loops.enable!
    end
    def process(source)
    visitors.inject(Parser.parse(source)) do |current, visitor|
    current.tap { |ast| ast.visit(visitor) }
    end.to_source
    end
    end
    @visitors = []
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  116. module Preval
    class << self
    attr_reader :visitors
    def enable_all!
    Visitors::Arithmetic.enable!
    Visitors::AttrAccessor.enable!
    Visitors::Fasterer.enable!
    Visitors::Loops.enable!
    end
    def process(source)
    visitors.inject(Parser.parse(source)) do |current, visitor|
    current.tap { |ast| ast.visit(visitor) }
    end.to_source
    end
    end
    @visitors = []
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  117. module Preval
    class << self
    attr_reader :visitors
    def enable_all!
    Visitors::Arithmetic.enable!
    Visitors::AttrAccessor.enable!
    Visitors::Fasterer.enable!
    Visitors::Loops.enable!
    end
    def process(source)
    visitors.inject(Parser.parse(source)) do |current, visitor|
    current.tap { |ast| ast.visit(visitor) }
    end.to_source
    end
    end
    @visitors = []
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  118. module Preval
    class Node
    def visit(pass)
    return if literal
    handler = :"on_#{type}"
    pass.public_send(handler, self) if pass.respond_to?(handler)
    return unless body.is_a?(Array)
    body.each do |child|
    child.visit(pass) if child.is_a?(Node)
    end
    end
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  119. class Preval::Visitors::Arithmetic < Visitor
    OPERATORS = %i[+ - * / % **].freeze
    def on_binary(node)
    left, operation, right = node.body
    return unless OPERATORS.include?(operation)
    if left.is?(:@int) && right.is?(:@int)
    value = left.to_int.public_send(operation, right.to_int)
    node.update(:@int, value.to_s)
    end
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  120. Demo
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  121. if defined?(Bootsnap)
    load_iseq = RubyVM::InstructionSequence.method(:load_iseq)
    if load_iseq.source_location[0].include?('/bootsnap/')
    Bootsnap::CompileCache::ISeq.singleton_class.prepend(
    Module.new do
    def input_to_storage(source, path)
    source = Preval.process(source)
    compiled =
    RubyVM::InstructionSequence.compile(
    source, path, path
    )
    compiled.to_binary
    rescue SyntaxError
    raise Bootsnap::CompileCache::Uncompilable
    end
    end
    )
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  122. if defined?(Bootsnap)
    load_iseq = RubyVM::InstructionSequence.method(:load_iseq)
    if load_iseq.source_location[0].include?('/bootsnap/')
    Bootsnap::CompileCache::ISeq.singleton_class.prepend(
    Module.new do
    def input_to_storage(source, path)
    source = Preval.process(source)
    compiled =
    RubyVM::InstructionSequence.compile(
    source, path, path
    )
    compiled.to_binary
    rescue SyntaxError
    raise Bootsnap::CompileCache::Uncompilable
    end
    end
    )
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  123. if defined?(Bootsnap)
    load_iseq = RubyVM::InstructionSequence.method(:load_iseq)
    if load_iseq.source_location[0].include?('/bootsnap/')
    Bootsnap::CompileCache::ISeq.singleton_class.prepend(
    Module.new do
    def input_to_storage(source, path)
    source = Preval.process(source)
    compiled =
    RubyVM::InstructionSequence.compile(
    source, path, path
    )
    compiled.to_binary
    rescue SyntaxError
    raise Bootsnap::CompileCache::Uncompilable
    end
    end
    )
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  124. if defined?(Bootsnap)
    load_iseq = RubyVM::InstructionSequence.method(:load_iseq)
    if load_iseq.source_location[0].include?('/bootsnap/')
    Bootsnap::CompileCache::ISeq.singleton_class.prepend(
    Module.new do
    def input_to_storage(source, path)
    source = Preval.process(source)
    compiled =
    RubyVM::InstructionSequence.compile(
    source, path, path
    )
    compiled.to_binary
    rescue SyntaxError
    raise Bootsnap::CompileCache::Uncompilable
    end
    end
    )
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  125. if defined?(Bootsnap)
    load_iseq = RubyVM::InstructionSequence.method(:load_iseq)
    if load_iseq.source_location[0].include?('/bootsnap/')
    Bootsnap::CompileCache::ISeq.singleton_class.prepend(
    Module.new do
    def input_to_storage(source, path)
    source = Preval.process(source)
    compiled =
    RubyVM::InstructionSequence.compile(
    source, path, path
    )
    compiled.to_binary
    rescue SyntaxError
    raise Bootsnap::CompileCache::Uncompilable
    end
    end
    )
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  126. if defined?(Bootsnap)
    load_iseq = RubyVM::InstructionSequence.method(:load_iseq)
    if load_iseq.source_location[0].include?('/bootsnap/')
    Bootsnap::CompileCache::ISeq.singleton_class.prepend(
    Module.new do
    def input_to_storage(source, path)
    source = Preval.process(source)
    compiled =
    RubyVM::InstructionSequence.compile(
    source, path, path
    )
    compiled.to_binary
    rescue SyntaxError
    raise Bootsnap::CompileCache::Uncompilable
    end
    end
    )
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  127. if defined?(Bootsnap)
    load_iseq = RubyVM::InstructionSequence.method(:load_iseq)
    if load_iseq.source_location[0].include?('/bootsnap/')
    Bootsnap::CompileCache::ISeq.singleton_class.prepend(
    Module.new do
    def input_to_storage(source, path)
    source = Preval.process(source)
    compiled =
    RubyVM::InstructionSequence.compile(
    source, path, path
    )
    compiled.to_binary
    rescue SyntaxError
    raise Bootsnap::CompileCache::Uncompilable
    end
    end
    )
    end
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  128. module Preval
    class << self
    attr_reader :visitors
    def enable_all!
    Visitors::Arithmetic.enable!
    Visitors::AttrAccessor.enable!
    Visitors::Fasterer.enable!
    Visitors::Loops.enable!
    end
    def process(source)
    visitors.inject(Parser.parse(source)) do |current, visitor|
    current.tap { |ast| ast.visit(visitor) }
    end.to_source
    end
    end
    @visitors = []
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  129. module Preval
    class << self
    attr_reader :visitors
    def enable_all!
    Visitors::Arithmetic.enable!
    Visitors::AttrAccessor.enable!
    Visitors::Fasterer.enable!
    Visitors::Loops.enable!
    end
    def process(source)
    visitors.inject(Parser.parse(source)) do |current, visitor|
    current.tap { |ast| ast.visit(visitor) }
    end.to_source
    end
    end
    @visitors = []
    end
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  130. Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  131. Optimizations
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  132. that can be done now
    Optimizations
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  133. that can be done now

    attr_accessor replacement
    Optimizations
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  134. that can be done now

    attr_accessor replacement

    instruction elimination
    Optimizations
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  135. that can be done now

    attr_accessor replacement

    instruction elimination
    that can be done with deoptimization
    Optimizations
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  136. that can be done now

    attr_accessor replacement

    instruction elimination
    that can be done with deoptimization

    for-loop replacement
    Optimizations
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  137. that can be done now

    attr_accessor replacement

    instruction elimination
    that can be done with deoptimization

    for-loop replacement

    constant folding
    Optimizations
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  138. that can be done now

    attr_accessor replacement

    instruction elimination
    that can be done with deoptimization

    for-loop replacement

    constant folding
    that a compiler can never do
    Optimizations
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  139. that can be done now

    attr_accessor replacement

    instruction elimination
    that can be done with deoptimization

    for-loop replacement

    constant folding
    that a compiler can never do

    replacing certain APIs with newer or faster APIs
    Optimizations
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  140. But why?
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  141. Style Progression
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  142. Nothing
    Style Progression
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  143. Nothing
    Senior devs enforce in code review
    Style Progression
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  144. Nothing
    Senior devs enforce in code review
    Style guide is developed and linked
    Style Progression
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  145. Nothing
    Senior devs enforce in code review
    Style guide is developed and linked
    Linters are developed and run locally (and in CI)
    Style Progression
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  146. Nothing
    Senior devs enforce in code review
    Style guide is developed and linked
    Linters are developed and run locally (and in CI)
    Auto-formatters and compilers take care of it
    Style Progression
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  147. Nothing
    Senior devs enforce in code review
    Style guide is developed and linked
    Linters are developed and run locally (and in CI)
    Auto-formatters and compilers take care of it
    Style Progression
    w
    e’re
    here
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  148. language: ruby
    rvm: 2.6.3
    branches:
    only: master
    before_install:
    - gem update --system
    - gem install bundler
    before_script: bundle exec rails db:create
    cache: bundler
    script:
    - bundle exec bundle audit
    - bin/rails test
    - bundle exec rubocop --parallel
    - bin/rails reek
    - bundle exec brakeman -z
    - bin/rails fasterer
    after_success: bin/deploy
    services:
    - postgresql
    - redis
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  149. language: ruby
    rvm: 2.6.3
    branches:
    only: master
    before_install:
    - gem update --system
    - gem install bundler
    before_script: bundle exec rails db:create
    cache: bundler
    script:
    - bundle exec bundle audit
    - bin/rails test
    - bundle exec rubocop --parallel
    - bin/rails reek
    - bundle exec brakeman -z
    - bin/rails fasterer
    after_success: bin/deploy
    services:
    - postgresql
    - redis
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation
    WHAT!?

    View full-size slide

  150. language: ruby
    rvm: 2.6.3
    branches:
    only: master
    before_install:
    - gem update --system
    - gem install bundler
    before_script: bundle exec rails db:create
    cache: bundler
    script:
    - bundle exec bundle audit
    - bin/rails test
    - bundle exec rubocop --parallel
    - bin/rails reek
    - bundle exec brakeman -z
    - bin/rails fasterer
    after_success: bin/deploy
    services:
    - postgresql
    - redis
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  151. language: ruby
    rvm: 2.6.3
    branches:
    only: master
    before_install:
    - gem update --system
    - gem install bundler
    before_script: bundle exec rails db:create
    cache: bundler
    script:
    - bundle exec bundle audit
    - bin/rails test
    - bundle exec rubocop --parallel
    - bin/rails reek
    - bundle exec brakeman -z
    - bin/rails fasterer
    after_success: bin/deploy
    services:
    - postgresql
    - redis
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  152. language: ruby
    rvm: 2.6.3
    branches:
    only: master
    before_install:
    - gem update --system
    - gem install bundler
    before_script: bundle exec rails db:create
    cache: bundler
    script:
    - bundle exec bundle audit
    - bin/rails test
    - bundle exec rubocop --parallel
    - bin/rails reek
    - bundle exec brakeman -z
    - bin/rails fasterer
    after_success: bin/deploy
    services:
    - postgresql
    - redis
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  153. language: ruby
    rvm: 2.6.3
    branches:
    only: master
    before_install:
    - gem update --system
    - gem install bundler
    before_script: bundle exec rails db:create
    cache: bundler
    script:
    - bundle exec bundle audit
    - bin/rails test
    - bundle exec rubocop --parallel
    - bin/rails reek
    - bundle exec brakeman -z
    - bin/rails fasterer
    after_success: bin/deploy
    services:
    - postgresql
    - redis
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  154. language: ruby
    rvm: 2.6.3
    branches:
    only: master
    before_install:
    - gem update --system
    - gem install bundler
    before_script: bundle exec rails db:create
    cache: bundler
    script:
    - bundle exec bundle audit
    - bin/rails test
    - bundle exec rubocop --parallel
    - bin/rails reek
    - bundle exec brakeman -z
    - bin/rails fasterer
    after_success: bin/deploy
    services:
    - postgresql
    - redis
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  155. language: ruby
    rvm: 2.6.3
    branches:
    only: master
    before_install:
    - gem update --system
    - gem install bundler
    before_script: bundle exec rails db:create
    cache: bundler
    script:
    - bin/rails test
    after_success: bin/deploy
    services:
    - postgresql
    - redis
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  156. Nothing
    Senior devs enforce in code review
    Style guide is developed and linked
    Linters are developed and run locally (and in CI)
    Auto-formatters and compilers take care of it
    Style Progression
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  157. Auto-formatters and compilers take care of it
    Style Progression
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  158. Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  159. Write code
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  160. Write code
    Test code
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  161. Write code
    Test code
    Deploy code
    Lexical Analytics • Semantic Analysis • Instruction Generation • Optimization • Ruby Compilation

    View full-size slide

  162. Pre-evaluation
    in Ruby
    github.com/kddeisz/preval
    Kevin Deisz
    @kddeisz

    View full-size slide