我正在使用 OpenStruct 来模仿 Active Record 结果:
require 'ostruct'
o1, o2, o3, o4 = [*(1..4)].map{ OpenStruct.new }
o1.kind = "att2"
o2.kind = "att3"
o3.kind = "att4"
o4.kind = "att1"
a = [o1, o2, o3, o4]
b = ['att1', 'att3', 'att4', 'att2']
a_hash = Hash[a.map{ |e| [e.kind, e] }]
a_hash # => {"att2"=>#<OpenStruct kind="att2">, "att3"=>#<OpenStruct kind="att3">, "att4"=>#<OpenStruct kind="att4">, "att1"=>#<OpenStruct kind="att1">}
new_a_order = a_hash.values_at(*b)
new_a_order # => [#<OpenStruct kind="att1">, #<OpenStruct kind="att3">, #<OpenStruct kind="att4">, #<OpenStruct kind="att2">]
基准时间:
require 'benchmark'
require 'ostruct'
o1, o2, o3, o4 = [*(1..4)].map{ OpenStruct.new }
o1.kind = "att2"
o2.kind = "att3"
o3.kind = "att4"
o4.kind = "att1"
a = [o1, o2, o3, o4]
b = ['att1', 'att3', 'att4', 'att2']
def tokland(a_ary, b_ary)
Hash[a_ary.map{ |e| [e.kind, e] }].values_at(*b_ary)
end
def bioneurlanet(a_ary, b_ary)
b_ary.map { |att| a_ary.detect { |obj| obj.kind == att } }
end
def mihai(a_ary, b_ary)
a_ary.sort_by do |element|
b_ary.index(element.kind)
end
end
N = 1_000_000
puts 'Ruby => ' + RUBY_VERSION
puts 'N => %d' % N
print 'tokland => ', tokland(a,b), "\n"
print 'bioneurlanet => ', bioneurlanet(a,b), "\n"
print 'mihai => ', mihai(a,b), "\n"
Benchmark.bm(12) do |x|
x.report('tokland') { N.times { tokland(a,b) }}
x.report('bioneurlanet') { N.times { bioneurlanet(a,b) }}
x.report('mihai') { N.times { mihai(a,b) }}
end
哪个输出:
Ruby => 2.0.0
N => 1000000
tokland => [#<OpenStruct kind="att1">, #<OpenStruct kind="att3">, #<OpenStruct kind="att4">, #<OpenStruct kind="att2">]
bioneurlanet => [#<OpenStruct kind="att1">, #<OpenStruct kind="att3">, #<OpenStruct kind="att4">, #<OpenStruct kind="att2">]
mihai => [#<OpenStruct kind="att1">, #<OpenStruct kind="att3">, #<OpenStruct kind="att4">, #<OpenStruct kind="att2">]
user system total real
tokland 2.890000 0.010000 2.900000 ( 2.885242)
bioneurlanet 4.430000 0.000000 4.430000 ( 4.434342)
mihai 3.180000 0.010000 3.190000 ( 3.189240)