简体   繁体   English

在使用大型集合(在Ruby中)时,为什么使用注入/减少比使用map.with_index更有效?

[英]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方法,我认为该方法比我拥有的mapwith_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM