ruby-on-rails – Ruby的范围步骤方法导致执行速度非常慢?

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – Ruby的范围步骤方法导致执行速度非常慢?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有这段代码
  1. date_counter = Time.mktime(2011,01,00,"+05:00")
  2. @weeks = Array.new
  3. (date_counter..Time.now).step(1.week) do |week|
  4. logger.debug "WEEK: " + week.inspect
  5. @weeks << week
  6. end

从技术上讲,代码有效,输出

  1. Sat Jan 01 00:00:00 -0500 2011
  2. Sat Jan 08 00:00:00 -0500 2011
  3. Sat Jan 15 00:00:00 -0500 2011
  4. etc.

但执行时间完全是垃圾!每周计算大约需要4秒钟.

我在这段代码中遗漏了一些奇怪的低效率吗?看起来很简单.

我正在使用Rails 3.0.3运行Ruby 1.8.7.

解决方法

假设MRI和Rubinius使用类似的方法生成范围,所有无关检查使用的基本算法和一些Fixnum优化等被删除是:
  1. class Range
  2. def each(&block)
  3. current = @first
  4. while current < @last
  5. yield current
  6. current = current.succ
  7. end
  8. end
  9.  
  10. def step(step_size,&block)
  11. counter = 0
  12. each do |o|
  13. yield o if counter % step_size = 0
  14. counter += 1
  15. end
  16. end
  17. end

(见the Rubinius source code)

对于Time对象,#succ会在一秒后返回时间.因此,即使你每周都要求它,但无论如何它必须在两次之间逐步完成.

编辑:解决方

构建一系列Fixnum,因为它们具有优化的Range#step实现.
就像是:

  1. date_counter = Time.mktime(2011,"+05:00")
  2. @weeks = Array.new
  3.  
  4. (date_counter.to_i..Time.now.to_i).step(1.week).map do |time|
  5. Time.at(time)
  6. end.each do |week|
  7. logger.debug "WEEK: " + week.inspect
  8. @weeks << week
  9. end

猜你在找的Ruby相关文章