Advertisement
Guest User

Untitled

a guest
Jul 21st, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.35 KB | None | 0 0
  1. require 'benchmark/ips'
  2.  
  3. class A
  4.  
  5. # def fib(n)
  6. # return n if n < 2
  7. # fib(n-2) + fib(n-1)
  8. # end
  9.  
  10. dynamic_method :fib do |g|
  11. g.required_args = 1
  12. g.total_args = 1
  13. g.local_count = 1
  14.  
  15. r0 = g.new_register
  16. r1 = g.new_register
  17. r2 = g.new_register
  18. r3 = g.new_register
  19.  
  20. done = g.new_label
  21.  
  22. g.r_load_local r0, 0
  23. g.r_load_int r1, r0
  24.  
  25. g.r_load_1 r3
  26. g.n_ile r2, r1, r3
  27. g.b_if r2, done
  28.  
  29. # n - 1
  30. g.n_isub r2, r1, r3
  31.  
  32. # n - 2
  33. g.n_isub r1, r2, r3
  34.  
  35. # fib(n - 2)
  36. g.push_self
  37. g.r_store_int r1, r1
  38. g.r_store_stack r1
  39. g.send :fib, 1, true
  40. g.r_load_stack r1
  41. g.r_load_int r1, r1
  42. g.pop
  43.  
  44. # fib(n - 1)
  45. g.push_self
  46. g.r_store_int r2, r2
  47. g.r_store_stack r2
  48. g.send :fib, 1, true
  49. g.r_load_stack r2
  50. g.r_load_int r2, r2
  51. g.pop
  52.  
  53. # +
  54. g.n_iadd r0, r1, r2
  55. g.r_store_int r0, r0
  56.  
  57. done.set!
  58. g.r_store_stack r0
  59. g.ret
  60. end
  61.  
  62. # def fibi(n)
  63. # return n if n < 2
  64. # i = 2
  65. # a = 1
  66. # b = 1
  67. # while i < n
  68. # t = a
  69. # a += b
  70. # b = t
  71. # i += 1
  72. # end
  73. # a
  74. # end
  75. dynamic_method :fibi do |g|
  76. g.required_args = 1
  77. g.total_args = 1
  78. g.local_count = 1
  79.  
  80. r0 = g.new_register
  81. r1 = g.new_register
  82. r2 = g.new_register
  83. r3 = g.new_register
  84. r4 = g.new_register
  85. r5 = g.new_register
  86. r6 = g.new_register
  87.  
  88. top = g.new_label
  89. body = g.new_label
  90. int = g.new_label
  91. done = g.new_label
  92.  
  93. g.r_load_1 r1
  94.  
  95. g.r_load_local r0, 0
  96. g.r_load_int r2, r0
  97.  
  98. # n <= 1
  99. g.n_ile r3, r2, r1
  100. g.b_if r3, done
  101.  
  102. # a = 1, r0
  103. g.r_load_1 r0
  104.  
  105. # b = 1, r3
  106. g.r_load_1 r3
  107.  
  108. # i = 2, r4
  109. g.n_iadd r4, r0, r0
  110.  
  111. top.set!
  112.  
  113. # i < n, r4 < r2
  114. # g.n_ilt r5, r4, r2
  115. # g.b_if r5, body
  116. # g.goto int
  117.  
  118. g.n_ige r5, r4, r2
  119. g.b_if r5, int
  120.  
  121. body.set!
  122.  
  123. # t = a, r6
  124. g.r_copy r6, r0
  125.  
  126. # a += b
  127. g.n_iadd r0, r0, r3
  128.  
  129. # b = t
  130. g.r_copy r3, r6
  131.  
  132. # i += 1
  133. g.n_iadd r4, r4, r1
  134.  
  135. # loop
  136. g.goto_past top
  137.  
  138. int.set!
  139. g.r_store_int r0, r0
  140.  
  141. done.set!
  142. g.r_store_stack r0
  143. g.ret
  144. end
  145. end
  146.  
  147. # puts A.instance_method(:fib).executable.decode
  148.  
  149. define_method(:fib, &A.new.method(:fib))
  150. define_method(:fibi, &A.new.method(:fibi))
  151.  
  152. p fib(40), fibi(40)
  153.  
  154. Benchmark.ips do |x|
  155. x.report 'fib(40)', %{ fib(40) }
  156. x.report 'fibi(40)', %{ fibi(40) }
  157. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement