[英]Why is using inject/reduce more efficient than using map.with_index when working with large collections (in Ruby)?
I was working on a Codewar problem and the method I came up with worked with small arrays, but didn't work for very large arrays. 我当时正在处理Codewar问题 ,我想出的方法适用于小型阵列,但不适用于大型阵列。
The solution provided used the inject
method, which I assume is more efficient than the combination of map
and with_index
I had. 提供的解决方案使用了
inject
方法,我认为该方法比我拥有的map
和with_index
组合的效率更高。
However, I'm not sure I understand why the inject
method is more efficient than looping. 但是,我不确定我为什么会理解为什么
inject
方法比循环更有效。 Could someone please shine some light on this? 有人可以照耀一下吗?
The problem was the following: Given an array, return an array where each element is the sum of the array's subparts. 问题如下:给定一个数组,返回一个数组,其中每个元素都是数组子部分的总和。
Example: array = [0, 1, 3, 6, 10]
示例:
array = [0, 1, 3, 6, 10]
I'm summing every array element while iterating on the array (so the array gets smaller and smaller): 我在迭代数组时对每个数组元素求和(因此数组变得越来越小):
[0, 1, 3, 6, 10] => 20
[1, 3, 6, 10] => 20
[3, 6, 10] => 19
[6, 10] => 16
[10] => 10
[] => 0
Hence the method would return here: [20, 20, 19, 16, 10, 0]
因此,该方法将在此处返回:
[20, 20, 19, 16, 10, 0]
My solution (which works for small arrays but is too inefficient for large arrays): 我的解决方案(适用于小型阵列,但不适用于大型阵列):
def parts_sums(ls)
(ls + [0]).map.with_index { |_, i| ls[i..-1].sum }
end
The provided solution: 提供的解决方案:
def parts_sums(ls)
ls.reduce([ls.sum]) { |sums, x| sums << sums.last - x }
end
By browsing the Codewars comment section, I've understood that this performance difference is linked to the Big O notation. 通过浏览Codewars注释部分,我了解到这种性能差异与Big O表示法相关。 However, every resource I found on this topic is way beyond my mathematical and algorithm understanding.
但是,我在该主题上发现的所有资源都远远超出了我对数学和算法的理解。
I've also looked at the Ruby doc but I don't understand C enough to be able to read the implementation of those methods. 我也看过Ruby文档,但我对C的理解不足,无法阅读这些方法的实现。
Could someone please explain in quite simple terms why inject
/ reduce
is more efficient than map.with_index
in this situation? 可能有人请解释很简单而言,为什么
inject
/ reduce
的效率比map.with_index
在这种情况呢?
Let's start with reduce
version. 让我们从
reduce
版本开始。
ls.reduce([ls.sum]) { |sums, x| sums << sums.last - x }
It sums an array once (on step zero,) and then it subtracts two integers on each subsequent iteration. 它对一个数组求和一次(在步骤零),然后在每次后续迭代中减去两个整数。
Your solution sums the tail of the array on each step. 您的解决方案将每一步的数组尾部求和 。 Summing requires the whole array traversal, that's why it is quite inefficient on large arrays.
求和需要整个数组遍历,这就是为什么在大型数组上效率很低的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.