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

ruby-on-rails – Ruby – 通过嵌套属性选择属于两个数组的项目

发布时间:2020-12-17 03:42:05 所属栏目:百科 来源:网络整理
导读:我的 Ruby查询非常慢.我正在寻找一种更快的方法来选择属于两个数组的项目 listA是具有属性名称的objectA列表 listB是具有属性名称的objectB的列表 listA中可以有多个项目具有相同的名称,但listB中没有任何项目具有相同的名称. listA中还有一些项目,其名称不
我的 Ruby查询非常慢.我正在寻找一种更快的方法来选择属于两个数组的项目

listA是具有属性名称的objectA列表

listB是具有属性名称的objectB的列表

listA中可以有多个项目具有相同的名称,但listB中没有任何项目具有相同的名称. listA中还有一些项目,其名称不在listB中.我想要一个函数(循环)来返回listA中名称在listB中的所有项目.

这是我目前的解决方案,但速度太慢了.我怎样才能让它更快?

z = 0
new = []
while z < listB.length 
    hold = listA.select{|obj| obj.name == listB[z].name}
    new += hold
    z += 1
end

解决方法

您希望最大化查找速度.查找的最佳速度是使用Hashes的O(1).下面描述的方法比你的代码快1000倍,比包含include的循环快350倍?对于n = 10000

编辑2:This link详细解释了为什么哈希查找速度快.

names = {}
listB.each{|item| names[item.name] = true}
result = listA.select{|item| names[item.name]}

编辑:更新基准.

> 03/08/2015 – 添加了user12341234 set方法

基准代码

class MyObject
  def initialize(name)
    @name = name
  end

  def name
    @name
  end
end

n=10000
k=n/10

listA = (1..n).map{ MyObject.new(('a'..'z').to_a.shuffle[0,8].join)}
listB = listA.sample(k)
listB += (1..(n-k)).map{ MyObject.new(('a'..'z').to_a.shuffle[0,8].join)}

require 'benchmark'
require 'set'

Benchmark.bm do |x|
    x.report("Hash") do
        names = {}
        listB.each{|item| names[item.name] = true}
        result = listA.select{|item| names[item.name]}
    end

    x.report("OP's code") do
        z = 0
        new = []
        while z < listB.length 
            hold = listA.select{|obj| obj.name == listB[z].name}
            new += hold
            z += 1
        end
    end

    x.report("Include") do
      names = listB.map(&:name)
      listA.select{|obj| names.include?(obj.name) }
    end

    x.report("Set") do 
        names = listB.map(&:name).to_set
        listA.select{|item| names.include?(item.name)}
    end
end

基准

眼镜 :

>英特尔酷睿i7 920 @ 2.67 GHz
> 13 GB RAM
> Windows 8 x64
> Ruby 21 x64

结果:

Algorithm       user     system      total        real
Hash         0.015000   0.000000   0.015000 (  0.013002)
OP's code   26.053000   0.016000  26.069000 ( 26.161283)
Include      9.219000   0.000000   9.219000 (  9.244161)
Set          0.016000   0.000000   0.016000 (  0.013001)

(编辑:李大同)

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

    推荐文章
      热点阅读