gpt4 book ai didi

ruby - 在 Ruby 中将两个数组相乘并获得相乘值之和的有效方法是什么?

转载 作者:数据小太阳 更新时间:2023-10-29 06:55:17 26 4
gpt4 key购买 nike

在 Ruby 中将两个数组相乘并获得相乘值之和的有效方法是什么?我在 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。

因为我需要在我的应用程序中对它们进行数百万次计算,进行此类计算的最有效方法是什么?

这就像矩阵计算:1* N 矩阵 * N*1 矩阵或向量点积。

最佳答案

更新

我刚刚根据新评论更新了基准。正在关注Joshua's comment ,注入(inject)方法将获得 25% 的加速,请参见下表中的 array walking without to_a

然而,由于速度是 OP 的主要目标,我们有 a new winner for the contest在我的基准测试中,这将运行时间从 .34 减少到 .22

我仍然更喜欢 inject 方法,因为它更像是 ruby​​-ish,但如果速度很重要,那么 while 循环似乎就是这种方式。

新答案

你总是可以对所有这些答案进行基准测试,我这样做是出于好奇:

> ./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)

简单的数组遍历胜出,Matrix 方法更差,因为它包含对象实例化。我认为如果你想打败 inject while 方法(在这里打败意味着最快一个数量级)你需要实现一个 C 扩展并将其绑定(bind)到您的 ruby​​ 程序中。

这是我用过的脚本

#!/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 - 在 Ruby 中将两个数组相乘并获得相乘值之和的有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7372489/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com