加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 23:23:20 所属栏目:百科 来源:网络整理
导读:我有这段代码: date_counter = Time.mktime(2011,01,00,"+05:00")@weeks = Array.new(date_counter..Time.now).step(1.week) do |week| logger.debug "WEEK: " + week.inspect @weeks weekend 从技术上讲,代码有效,输出: Sat Jan 01 00:00:00 -0500 2011Sa
我有这段代码:
date_counter = Time.mktime(2011,01,00,"+05:00")
@weeks = Array.new
(date_counter..Time.now).step(1.week) do |week|
   logger.debug "WEEK: " + week.inspect
   @weeks << week
end

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

Sat Jan 01 00:00:00 -0500 2011
Sat Jan 08 00:00:00 -0500 2011
Sat Jan 15 00:00:00 -0500 2011
etc.

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

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

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

解决方法

假设MRI和Rubinius使用类似的方法生成范围,所有无关检查使用的基本算法和一些Fixnum优化等被删除是:
class Range
  def each(&block)
    current = @first
    while current < @last
      yield current
      current = current.succ
    end
  end

  def step(step_size,&block)
    counter = 0
    each do |o|
      yield o if counter % step_size = 0
      counter += 1
    end
  end
end

(见the Rubinius source code)

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

编辑:解决方案

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

date_counter = Time.mktime(2011,"+05:00")
@weeks = Array.new

(date_counter.to_i..Time.now.to_i).step(1.week).map do |time|
  Time.at(time)
end.each do |week|
  logger.debug "WEEK: " + week.inspect
  @weeks << week
end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读