如何加快该Rails代码的速度?

问题描述

| 我知道这是一个模糊的问题。...但是这段代码的性能太糟糕了。从原始帖子到操作到呈现页面大约需要15秒... 此操作的目的是从简历中检索所有职业,该简历中的所有技能以及职业。它们需要按2个数组进行组织: 第一个数组包含所有职业(无重复),并根据得分排序。 Fo每个两次进入均发现分数增加1 第二个数组包含职业数组和简历中的所有技能。再次不允许双打,但是每遇到一个双打,现有分数就会增加一。 下面是执行此操作的代码块。与我的其他代码段相比,它相对较大,但我希望它是可以理解的。我知道像我一样使用数组会令人困惑,但这是每个数组位置的含义: 位置0:实际的技能/职业对象 位置1:条目得分 位置2:在数据库中找到的位置 位置3:在简历中找到的位置   def归类
@cv = Cv.find(params[:cv_id],:include => [:desired_occupations,:past_occupations,:educational_skills])
@menu = :second
@language = Language.resolve(:code => :en,:name => :en)
@occupation_hashes = []
@skill_hashes = []

(@cv.desired_occupations + @cv.past_occupations).each do |occupation|
  section = []
  section << \'Desired occupation\' if @cv.desired_occupations.include? occupation
  section << \'Work experience\' if @cv.past_occupations.include? occupation

  unless (array = @occupation_hashes.assoc(occupation)).blank?
    array[1] += 1
    array[2] = (array[2] & section).uniq
  else
    @occupation_hashes << [occupation,1,section]
  end

  occupation.skills.each do |skill|
    unless (array = @skill_hashes.assoc skill).blank?
      label = occupation.concept.label(@language).value
      array[1]+= 1
      array[3] << label unless array[3].include? label
    else
      @skill_hashes << [skill,[],[occupation.concept.label(@language).value]]
    end
  end
end

@cv.educational_skills.each do |skill|
  unless (array = @skill_hashes.assoc skill).blank?
    array[1]+= 1
    array[3] << \'Education skills\' unless array[3].include? \'Education skills\'
  else
    @skill_hashes << [skill,[\'Education skills\'],[]]
  end
end

# Sort the hashes
@occupation_hashes.sort! { |x,y| y[1] <=> x[1]}
@skill_hashes.sort! { |x,y| y[1] <=> x[1]}

@max = @skill_hashes.first[1]
@min = @skill_hashes.last[1] end
我可以发布其他模型和迁移信息,以明确每个类的作用,但是我认为上述脚本的前几行应该在关联上清晰明了。我正在寻找一种优化每个循环的方法...     

解决方法

那是相当的代码块。通常,如果您编写的方法很严重,将来将很难维护它。一种有用的技术是将完整的代码块分解成一个帮助器类,以更逻辑的阶段进行处理,从而更轻松地微调代码的各个方面。 例如,接口可能是:
@categorizer = CvCategorizer.new(params[:cv_id])
这将封装以上所有内容,并将其保存到实例变量中,该实例变量通过用
attr_reader
声明可以访问。 使用实用程序类意味着您可以将初始化分解为更清晰的步骤:
def initialize(cv_id)
  # Call a wrapper method that loads the CV
  @cv = self.load_cv(cv_id)

  # Perform discrete steps to re-order the imported data
  self.organize_occupations
  self.organize_skills
end
虽然我会特别注意is4ѭ以查看其中的情况,但是很难仅凭它说出为什么它会变慢。可能是初始加载非常缓慢,但其余方法都很好。     ,您应该对代码进行概要分析,以查看花费了很多时间。您可以弄清楚如何使用探查器,或者在整个代码中撒一些简单的
puts
logger.info
语句并加上时间戳。使用ѭ7by可能最容易做到这一点。注意:您可能需要
require \'benchmark\'
...不确定在Rails中是否需要它。 对于一行,您可以执行以下操作:
    logger.info Benchmark.measure { @cv = Cv.find(params[:cv_id],:include => [:desired_occupations,:past_occupations,:educational_skills]) }
为了定时更大的代码块:
logger.info Benchmark.measure do
  (@cv.desired_occupations + @cv.past_occupations).each do |occupation|
    section = []
    section << \'Desired occupation\' if @cv.desired_occupations.include? occupation
    section << \'Work experience\' if @cv.past_occupations.include? occupation

    unless (array = @occupation_hashes.assoc(occupation)).blank?
      array[1] += 1
      array[2] = (array[2] & section).uniq
    else
      @occupation_hashes << [occupation,1,section]
    end
  end
end
我只是从大块开始,然后缩小范围。不知道要处理的数据集有多大,很难说出问题区域是什么。 我也将与其他人达成共识,将您的情况更好地分解为更小的方法。您还可以执行以下操作,从而更轻松地测试性能:
Benchmark.measure { 10000.times { foo.do_that_thing_that_might_be_slow }} 
    

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...