什么是乘两个阵列和在Ruby中获得倍增的值的总和的有效途径? [英] What's the efficient way to multiply two arrays and get sum of multiplied values in Ruby?
问题描述
什么是乘两个阵列和在Ruby中获得乘法值的总和的有效途径?
我有两个数组在Ruby中:
What's the efficient way to multiply two arrays and get sum of multiply values in Ruby? I have two arrays in Ruby:
array_A = [1, 2, 1, 4, 5, 3, 2, 6, 5, 8, 9]
array_B = [3, 2, 4, 2, 5, 1, 3, 3, 7, 5, 4]
我的目标是获得array_A * array_B的总和值,即,1 * 3 + 2 * 2 + 1 * 4 + ... 8 * 5 + 9 * 4
My aim is to get the sum value of array_A * array_B, i.e., 1*3 + 2*2 + 1*4 + ... + 8*5 + 9*4.
由于我需要计算它们万次在我的应用程序,什么是做这样的计算,最有效的方法是什么?
Because I need to calculate them million times in my apps, what's the most efficient way to do such calculations?
这就像一个矩阵测算:1 * N矩阵* N * 1矩阵,向量的点积
It's just like a matrix calcuation: 1* N matrix * N*1 matrix or a vector dot product.
推荐答案
更新
我根据新的评论已经刚刚更新的基准。继<一个href=\"http://stackoverflow.com/questions/7372489/whats-the-efficient-way-to-multiply-two-arrays-and-get-sum-of-multiplied-values/7372688#comment-8900059\">Joshua's评论的注射方法将获得25%的增速,见阵列,而不走to_a
下表。
I've just updated benchmarks according to new comments. Following Joshua's comment, the inject method will gain a 25% speedup, see array walking without to_a
in the table below.
然而,由于速度是我们的<一个OP的首要目标href=\"http://stackoverflow.com/questions/7372489/whats-the-efficient-way-to-multiply-two-arrays-and-get-sum-of-multiplied-values/7373434#7373434\">a为减少从 0.34
运行时 0.22
在我的基准竞赛的新赢家。
However since speed is the primary goal for the OP we have a new winner for the contest which reduces runtime from .34
to .22
in my benchmarks.
我还是preFER 注射
的方法,因为它更红宝石十岁上下,但如果速度方面则while循环似乎是这样。
I still prefer inject
method because it's more ruby-ish, but if speed matters then the while loop seems to be the way.
新建答案
您可以随时基准所有这些问题的答案,我这样做是出于好奇:
You can always benchmark all these answers, I did it for curiosity:
> ./matrix.rb
Rehearsal --------------------------------------------------------------
matrix method 1.500000 0.000000 1.500000 ( 1.510685)
array walking 0.470000 0.010000 0.480000 ( 0.475307)
array walking without to_a 0.340000 0.000000 0.340000 ( 0.337244)
array zip 0.590000 0.000000 0.590000 ( 0.594954)
array zip 2 0.500000 0.000000 0.500000 ( 0.509500)
while loop 0.220000 0.000000 0.220000 ( 0.219851)
----------------------------------------------------- total: 3.630000sec
user system total real
matrix method 1.500000 0.000000 1.500000 ( 1.501340)
array walking 0.480000 0.000000 0.480000 ( 0.480052)
array walking without to_a 0.340000 0.000000 0.340000 ( 0.338614)
array zip 0.610000 0.010000 0.620000 ( 0.625805)
array zip 2 0.510000 0.000000 0.510000 ( 0.506430)
while loop 0.220000 0.000000 0.220000 ( 0.220873)
简单数组行走胜,阵法更糟糕的是,因为它包含对象的实例。我认为,如果你想击败的<击> 注射
行使> ,而
方法(在这里击败手段幅度最快的顺序),你需要实现一个 C
扩展,在你的Ruby程序绑定。
Simple array walking wins, Matrix method is worse because it includes object instantiation. I think that if you want to beat the inject
while
method (to beat here means an order of magnitude fastest) you need to implement a C
extension and bind it in your ruby program.
这是我使用的脚本
#!/usr/bin/env ruby
require 'benchmark'
require 'matrix'
array_A = [1, 2, 1, 4, 5, 3, 2, 6, 5, 8, 9]
array_B = [3, 2, 4, 2, 5, 1, 3, 3, 7, 5, 4]
def matrix_method a1, a2
(Matrix.row_vector(a1) * Matrix.column_vector(a2)).element(0,0)
end
n = 100000
Benchmark.bmbm do |b|
b.report('matrix method') { n.times { matrix_method(array_A, array_B) } }
b.report('array walking') { n.times { (0...array_A.count).to_a.inject(0) {|r, i| r + array_A[i]*array_B[i]} } }
b.report('array walking without to_a') { n.times { (0...array_A.count).inject(0) {|r, i| r + array_A[i]*array_B[i]} } }
b.report('array zip') { n.times { array_A.zip(array_B).map{|i,j| i*j }.inject(:+) } }
b.report('array zip 2') { n.times { array_A.zip(array_B).inject(0) {|r, (a, b)| r + (a * b)} } }
b.report('while loop') do
n.times do
sum, i, size = 0, 0, array_A.size
while i < size
sum += array_A[i] * array_B[i]
i += 1
end
sum
end
end
end
这篇关于什么是乘两个阵列和在Ruby中获得倍增的值的总和的有效途径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!