Guest User

Untitled

a guest
Jun 23rd, 2018
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.33 KB | None | 0 0
  1.  
  2. # bad use of metaprogramming
  3. module MetaTimeDSL
  4.  
  5. {:second => 1,
  6. :minute => 60,
  7. :hour => 3600,
  8. :day => [24,:hours],
  9. :week => [7,:days],
  10. :month => [30,:days],
  11. :year => [364.25, :days]}.each do |meth, amount|
  12. define_method "m_#{meth}" do
  13. amount = amount.is_a?(Array) ? amount[0].send(amount[1]) : amount
  14. self * amount
  15. end
  16. alias_method "m_#{meth}s".intern, "m_#{meth}"
  17. end
  18.  
  19. end
  20. Numeric.send :include, MetaTimeDSL
  21.  
  22.  
  23.  
  24. # Rewrite
  25. module TimeDSL
  26.  
  27. def second
  28. self * 1
  29. end
  30. alias_method :seconds, :second
  31.  
  32. def minute
  33. self * 60
  34. end
  35. alias_method :minutes, :minute
  36.  
  37. def hour
  38. self * 3600
  39. end
  40. alias_method :hours, :hour
  41.  
  42. def day
  43. self * 86400
  44. end
  45. alias_method :days, :day
  46.  
  47. def week
  48. self * 604800
  49. end
  50. alias_method :weeks, :week
  51.  
  52. def month
  53. self * 18144000
  54. end
  55. alias_method :months, :month
  56.  
  57. def year
  58. self * 31471200
  59. end
  60. alias_method :years, :year
  61.  
  62. end
  63. Numeric.send :include, TimeDSL
  64.  
  65. module RefaMetaTimeDSL
  66.  
  67. {:second => 1,
  68. :minute => 60,
  69. :hour => 3600,
  70. :day => [24,:hours],
  71. :week => [7,:days],
  72. :month => [30,:days],
  73. :year => [364.25, :days]}.each do |meth, amount|
  74. self.class_eval <<-RUBY
  75. def r_#{meth}
  76. #{amount.is_a?(Array) ? "#{amount[0]}.#{amount[1]}" : "#{amount}"}
  77. end
  78. alias_method :r_#{meth}s, :r_#{meth}
  79. RUBY
  80. end
  81.  
  82. end
  83. Numeric.send :include, RefaMetaTimeDSL
  84.  
  85. module EvalMetaTimeDSL
  86. def self.included(base)
  87. base.class_eval do
  88. [ [:e_second, 1],
  89. [:e_minute, 60],
  90. [:e_hour, 3600],
  91. [:e_day, [24,:e_hours]],
  92. [:e_week, [7,:e_days]],
  93. [:e_month, [30,:e_days]],
  94. [:e_year, [365.25, :e_days]]].each do |meth, amount|
  95. amount = amount.is_a?(Array) ? amount[0].send(amount[1]) : amount
  96. eval "def #{meth}; self*#{amount}; end"
  97. alias_method "#{meth}s", meth
  98. end
  99. end
  100. end
  101. end
  102. Numeric.send :include, EvalMetaTimeDSL
  103.  
  104. module GoodMetaTimeDSL
  105.  
  106. SECOND = 1
  107. MINUTE = SECOND * 60
  108. HOUR = MINUTE * 60
  109. DAY = HOUR * 24
  110. WEEK = DAY * 7
  111. MONTH = DAY * 30
  112. YEAR = DAY * 364.25
  113.  
  114. %w[SECOND MINUTE HOUR DAY WEEK MONTH YEAR].each do |const_name|
  115. meth = const_name.downcase
  116. class_eval <<-RUBY
  117. def g_#{meth}
  118. self * #{const_name}
  119. end
  120. alias g_#{meth}s g_#{meth}
  121. RUBY
  122. end
  123. end
  124. Numeric.send :include, GoodMetaTimeDSL
  125.  
  126.  
  127.  
  128. ###############################
  129. #
  130. #
  131. # Benchmarks
  132. require "rubygems"
  133. require "rbench"
  134.  
  135. TIMES = 100_000
  136.  
  137. RBench.run(TIMES) do
  138.  
  139. format :width => 65
  140.  
  141. column :times
  142. column :bad_meta, :title => "Bad Neta"
  143. column :no_meta, :title => "No Meta"
  144. column :refa, :title => "Refactored"
  145. column :eval_meta, :title => 'Refactor 2'
  146. column :good_meta, :title => "Better Meta"
  147.  
  148. group("MetaTimeDSL") do
  149. report "with 360.seconds" do
  150. bad_meta { 360.m_seconds }
  151. no_meta { 360.seconds }
  152. refa { 360.r_seconds }
  153. eval_meta { 360.e_seconds}
  154. good_meta { 360.g_seconds }
  155. end
  156.  
  157. report "with 360.minutes" do
  158. bad_meta { 360.m_minutes }
  159. no_meta { 360.minutes }
  160. refa { 360.r_minutes }
  161. eval_meta { 360.e_minutes }
  162. good_meta { 360.g_minutes }
  163. end
  164.  
  165. report "with 360.hours" do
  166. bad_meta { 360.m_hours }
  167. no_meta { 360.hours }
  168. refa { 360.r_hours }
  169. eval_meta { 360.e_hours }
  170. good_meta { 360.g_hours }
  171. end
  172.  
  173. report "with 360.days" do
  174. bad_meta { 360.m_days }
  175. no_meta { 360.days }
  176. refa { 360.r_days }
  177. eval_meta { 360.e_days }
  178. good_meta { 360.g_days }
  179. end
  180. report "with 360.weeks" do
  181. bad_meta { 360.m_weeks }
  182. no_meta { 360.weeks }
  183. refa { 360.r_weeks }
  184. eval_meta { 360.e_weeks }
  185. good_meta { 360.g_weeks }
  186. end
  187. report "with 18.months" do
  188. bad_meta { 18.m_months }
  189. no_meta { 18.months }
  190. refa { 18.r_months }
  191. eval_meta { 18.e_months }
  192. good_meta { 18.g_months }
  193. end
  194. report "with 7.years" do
  195. bad_meta { 7.m_years }
  196. no_meta { 7.years }
  197. refa { 7.r_years }
  198. eval_meta { 7.e_years }
  199. good_meta { 7.g_years }
  200. end
  201.  
  202. end
  203. end
  204.  
  205. #####
  206. #
  207. #                                  | Bad Neta | No Meta | Refactored | Refactor 2 | Better Meta |
  208. # --MetaTimeDSL----------------------------------------------------------------------------------
  209. # with 360.seconds         x100000 |    0.143 |   0.046 |      0.033 |      0.047 |       0.048 |
  210. # with 360.minutes         x100000 |    0.152 |   0.045 |      0.033 |      0.046 |       0.046 |
  211. # with 360.hours           x100000 |    0.127 |   0.044 |      0.032 |      0.045 |       0.048 |
  212. # with 360.days            x100000 |    0.144 |   0.047 |      0.070 |      0.045 |       0.048 |
  213. # with 360.weeks           x100000 |    0.129 |   0.044 |      0.070 |      0.046 |       0.047 |
  214. # with 18.months           x100000 |    0.143 |   0.045 |      0.071 |      0.045 |       0.048 |
  215. # with 7.years             x100000 |    0.143 |   0.046 |      0.089 |      0.054 |       0.050 |
  216. #
  217. ####
Add Comment
Please, Sign In to add comment