Your SlideShare is downloading. ×
RubyConf Argentina 2011
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

RubyConf Argentina 2011

12,625
views

Published on

RubyConf Argentina 2011

RubyConf Argentina 2011

Published in: Technology, Business

0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
12,625
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
29
Comments
0
Likes
8
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Who makes the best Asado?
  • 2. What country has the best footballers?
  • 3. Argentina!
  • 4. river
  • 5. riverNacional B???
  • 6. NOOOOOOOO!!!!
  • 7. Aaron Patterson
  • 8. @tenderlove
  • 9. Ruby core team
  • 10. Rails core team
  • 11. ! WARNING !
  • 12. ZOMG!
  • 13. We are in Argentina!
  • 14. José Yo
  • 15. WWFMD?
  • 16. me gusta
  • 17. ¿Por qué Maria?
  • 18. THANKS!!
  • 19. ResourceManagement
  • 20. Path Management
  • 21. Move bet ween theory and practice PatternMatching
  • 22. Graphviz http://graphviz.org
  • 23. greetinghello world
  • 24. graph.dotdigraph nfa { rankdir=LR; world [shape = doublecircle]; hello [shape = circle]; hello -> world [label="greeting"];}
  • 25. graph.dotdigraph nfa { rankdir=LR; world [shape = doublecircle]; hello [shape = circle]; goodbye [shape = circle]; hello -> world [label="greeting"]; goodbye -> world}
  • 26. hello greeting worldgoodbye
  • 27. /articles(.:format) / articles . (?-mix:[^./?]+)0 1 2 3 5 / new 4 6 /articles/new(.:format)
  • 28. Journey
  • 29. JourneyYes, its named after the 70s rock sensation
  • 30. Provides 1: URL generation 2: Path Recognition 3: Route parsingWhat is a router?
  • 31. Why a new router?
  • 32. Maintenance
  • 33. LOC300022501500 750 0 Journey Journey-2 Rack-Mount
  • 34. Known algorithms
  • 35. References• Compilers: Principles, Techniques, & Tools (Aho, Lam, Sethi, Ullman)• Intro to Formal Languages and Automata (Linz)
  • 36. Predictability
  • 37. CPU Time
  • 38. Memory Usage
  • 39. Current Performance rack-mount Journey url generation path recognition route parsing
  • 40. me gusta
  • 41. Patterns
  • 42. Why patterns matter
  • 43. Regular Expressions /om(g)!/
  • 44. Rails Routes
  • 45. resource :articles
  • 46. /articles(.:format)/articles/new(.:format)/articles/:id/edit(.:format)/articles/:id(.:format)
  • 47. Parens dont capture
  • 48. :whatever => /([^./?]+)/
  • 49. /articles(.:format)//articles(?:.([^./?]+))?$/
  • 50. //articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/
  • 51. GET /articles/new//articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/
  • 52. GET /articles/new//articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/
  • 53. GET /articles/new//articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/ 200 OK!
  • 54. //articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/
  • 55. GET /foos/new//articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/
  • 56. GET /foos/new//articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/
  • 57. GET /foos/new//articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/
  • 58. GET /foos/new//articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/
  • 59. GET /foos/new//articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/
  • 60. GET /foos/new//articles(?:.([^./?]+))?$///articles/new(?:.([^./?]+))?$///articles/([^./?]+)/edit(?:.([^./?]+))?$///articles/([^./?]+)(?:.([^./?]+))?$/ 404 Not Found
  • 61. How long does this take?
  • 62. r = routes.length
  • 63. x = regexp compare
  • 64. O(r ⨉ x)
  • 65. Can we do better?
  • 66. Parse Trees AutomataFinite State Machines
  • 67. Parse Trees
  • 68. Parsing regexp
  • 69. (a|b)*abb
  • 70. ○ Describe node types ○ b○ ba * () | a b
  • 71. Parsing rails routes
  • 72. Journey::Parserparser = Journey::Parser.newast = parser.parse /articles(.:format)puts ast.to_dot
  • 73. ○ ○ ()/ articles ○ . :format
  • 74. To String!parser = Journey::Parser.newast = parser.parse /articles(.:format)puts ast.to_sputs ast.to_regexp
  • 75. OR ASTparser = Journey::Parser.newtrees = [ /articles(.:format), /articles/new(.:format),].map { |s| parser.parse s }ast = Journey::Nodes::Or.new treesputs ast.to_dot
  • 76. | ○ ○ ○ () ○ ()/ articles ○ ○ new ○ . :format ○ / . :format / articles
  • 77. SECRET FEATUREparser = Journey::Parser.newast = parser.parse /articles|books(.:format)
  • 78. SECRET FEATUREparser = Journey::Parser.new RE T! ECast = parser.parse /articles|books(.:format) RS SU PE
  • 79. Automata
  • 80. (a|b)*abb
  • 81. Double circle is acceptance state b a a b b 0 1 a a 23 b
  • 82. baabb
  • 83. b a a b b 0 1 a a 23 b
  • 84. b b a a b b 0 1 a a 23 b
  • 85. ba b a a b b 0 1 a a 23 b
  • 86. baa b a a b b 0 1 a a 23 b
  • 87. baabb b a a b b 0 1 a a 23 b
  • 88. aab b a a b b 0 1 a a 23 b
  • 89. Deterministic Finite Automaton
  • 90. Only one path
  • 91. Storageclass DFA attr_reader :table def initialize @table = Hash.new { |h, from| h[from] = {} } @table[0][a] = 1 @table[0][b] = 0 @table[1][a] = 1 @table[1][b] = 2 @table[2][a] = 1 @table[2][b] = 3 @table[3][b] = 0 @table[3][a] = 2 endend
  • 92. FSM Simulation
  • 93. class Simulator def initialize(dfa) @dfa = dfa end def simulate(symbols) state = 0 until symbols.empty? state = @dfa.move(state, symbols.shift) end state endend
  • 94. move functionclass DFA ... def move(from, symbol) @table[from][symbol] endend
  • 95. irb> sim = Simulator.new(DFA.new)=> #<Simulator:0x007f95929a82e0 ...>irb> sim.simulate %w{ b a a b b }=> 3irb> sim.simulate %w{ a a b }=> 2
  • 96. Time: O(n) n = string.length
  • 97. me gusta
  • 98. Space: S + Tstates.length + transitions.length
  • 99. NondeterministicFinite Automaton
  • 100. Has nil edges
  • 101. Cant tell direction
  • 102. Simulation of NFA
  • 103. a|b a ε 2 3 ε0 ε ε 6 b 4 5
  • 104. nil-closure a ε 2 3 ε0 ε ε 6 b 4 5
  • 105. a a ε 2 3 ε0 ε ε 6 b 4 5
  • 106. Storageclass NFA def initialize @table = Hash.new { |h, from| h[from] = Hash.new { |i,sym| i[sym] = [] } } @table[0][nil] << 2 @table[0][nil] << 4 @table[2][a] << 3 @table[4][b] << 5 @table[3][nil] << 6 @table[5][nil] << 6 end def nil_closure(states) states.map { |s| @table[s][nil] }.flatten endend
  • 107. FSM Simulationclass Simulator def initialize(nfa) @nfa = nfa end def simulate(symbols) states = @nfa.nil_closure([0]) until symbols.empty? next_s = @nfa.move(states, symbols.shift) states = @nfa.nil_closure(next_s) end states endend
  • 108. Move functionclass NFA ... def move(states, symbol) states.map { |s| @table[s][symbol] }.flatten endend
  • 109. irb> sim = Simulator.new(NFA.new)=> #<Simulator:0x007faa188a5f88 ...>irb> sim.simulate %w{ a }=> [6]irb> sim.simulate %w{ b }=> [6]irb> sim.simulate %w{ b b }=> []irb> sim.simulate %w{ c }=> []
  • 110. Time: O(r ⨉ x)r = operators.length, x = string.length
  • 111. Who cares about NFA?
  • 112. NFA Construction
  • 113. /articles(.:format) ○ ○ () / articles ○ . :format
  • 114. cat nodes /0 1
  • 115. /articles / articles0 1 2
  • 116. Optional ε0 ε ????? ε 3 1 2
  • 117. ε / articles0 1 2 ε ε 6 . :format 3 4 5
  • 118. Journey::NFAparser = Journey::Parser.newast = parser.parse /articles(.:format)nfa = Journey::NFA::Builder.new asttt = nfa.transition_tableputs tt.to_dot
  • 119. ConvertingNFA to DFA
  • 120. Eliminate nil transitions
  • 121. Collapse duplicate edges
  • 122. /articles(.:format) ε / articles0 1 2 ε ε 6 . :format 3 4 5
  • 123. /articles(.:format) / articles . :format0 1 2 3 4
  • 124. CODES!parser = Journey::Parser.newast = parser.parse /articles(.:format)nfa = Journey::NFA::Builder.new asttt = nfa.transition_table.generalized_tableputs tt.to_dot
  • 125. SHORTER CODES!parser = Journey::Parser.newast = parser.parse /articles(.:format)dfa = Journey::GTG::Builder.new asttt = dfa.transition_tableputs tt.to_dot
  • 126. ANY NFAconverts to DFA
  • 127. O(r ⨉ x) => O(x)r = operations.length, x = string.length
  • 128. me gusta
  • 129. Converting Automata to Regexp
  • 130. /articles(.:format) / articles . :format0 1 2 3 4
  • 131. /articles(.:format) /articles . :format0 2 3 4
  • 132. /articles(.:format) /articles .:format0 2 4
  • 133. /articles(.:format) /articles(.:format)?0 4
  • 134. GeneralizedTransition Graph
  • 135. resource :users/users(.:format)/users/new(.:format)/users/:id/edit(.:format)/users/:id(.:format)
  • 136. resource :users (?-mix:[^./?]+) . 3 5 / users0 1 2 / new . (?-mix:[^./?]+) 4 6 8 11 (?-mix:[^./?]+) / edit . (?-mix:[^./?]+) 7 9 12 14 15 . (?-mix:[^./?]+) 10 13
  • 137. The Plan?
  • 138. Combine All Routes
  • 139. Produce DFA
  • 140. Simulate in O(n) Time
  • 141. Routing To The Future
  • 142. JS Simulation
  • 143. Table => JSONparser = Journey::Parser.newast = parser.parse /articles(.:format)dfa = Journey::GTG::Builder.new asttt = dfa.transition_tableputs tt.to_json
  • 144. Table => SVGparser = Journey::Parser.newast = parser.parse /articles(.:format)dfa = Journey::GTG::Builder.new asttt = dfa.transition_tableputs tt.to_svg
  • 145. JS Tokenizerfunction tokenize(input, callback) { while(input.length > 0) { callback(input.match(/^[/.?]|[^/.?]+/)[0]); input = input.replace(/^[/.?]|[^/.?]+/, ); }}
  • 146. JS Simulatortokenize(input, function(token) { var new_states = []; for(var key in states) { var state = states[key]; if(string_states[state] && string_states[state][token]) { var new_state = string_states[state][token]; highlight_edge(state, new_state); highlight_state(new_state); new_states.push(new_state); } } if(new_states.length == 0) { return; } states = new_states;});
  • 147. d3.js
  • 148. Rails Consoleirb> File.open(out.html, wb) { |f|irb* f.write(irb* Wot::Application.routes.router.visualizerirb> )}=> 69074
  • 149. routes.rb marshalling
  • 150. Test suggestions
  • 151. Test coverage
  • 152. Usage Heat Maps
  • 153. ASTREGEXP NFA DFA
  • 154. ROFLSCALE!!!
  • 155. DFA => YACC
  • 156. DFA => RACC
  • 157. DFA => Ragel
  • 158. Open Questions
  • 159. Is our GTGdeterministic?
  • 160. /users/new|/users/:id new 4 / users / (?-mix:[^./?]+)0 1 2 3 5
  • 161. "new" =~ /new|[^./?]+/
  • 162. Can we make itdeterministic?
  • 163. L1 = {new}L2 = {[^./?]+}
  • 164. /users/new|/users/:id L1 4 / users / L2 - L10 1 2 3 5
  • 165. Is it worth our effort?
  • 166. ASTREGEXP NFA DFA
  • 167. Is it worth our effort?
  • 168. Thank You!!
  • 169. <3<3<3<3<3