我正在尝试在具有6k项和30k用户的小型数据库中执行集体过滤相似性算法。这是我大学的一个研究项目;我不是计算机科学家;而是一个超级用户。数据已经用特定键指定;为了节省计算机时间,我创建了与现有密钥的关联。
在我的算法中,此代码段的执行时间最长:
def aveRankings(item,user = nil)
#period
begdate = '2013-08-10 00:00:00 -0400' #Time.parse('2013-08-10')
enddate = '2014-08-10 00:00:00 -0400' #Time.parse('2014-08-10')
if user.nil? then
return item.rankings.where(created_at: (begdate..enddate) ).average(:value).to_f
else
return user.items.where(created_at: (begdate..enddate), ikey: item.ikey).average(:value).to_f
end
end
我在网上读到有关n + 1以及它如何背叛性能的内容。我试着调用.include(:排名)来急切加载排名,但代码的行为并不像预期的那样。
这是与项目的关联:
class Item < ActiveRecord::Base
.
.
has_many :useritems, foreign_key: "ukey", primary_key: "ukey"
has_many :items, through: :useritems
.
.
end
非常感谢任何建议。
编辑:我应该包含这个
commonUsers.each do |commonuser|
a = aveRankings(item,commonuser)
b = aveRankings(candidateitem,commonuser)
if a != 0.0 and b != 0.0 then #mysql ave function returns this for 0 rankings
arra << a - aveRankings(item)
arrb << b - aveRankings(candidateitem)
end
end
答案 0 :(得分:0)
这里是你如何避免至少3/4的请求:
aa = aveRankings(item)
bb = aveRankings(candidateitem)
a = nil
commonUsers.each do |commonuser|
a = a || aveRankings(item,commonuser)
b = aveRankings(candidateitem,commonuser)
if a != 0.0 and b != 0.0 then #mysql ave function returns this for 0 rankings
arra << a - aa
arrb << b - bb
end
end