【问题标题】:How does one do asymptotic analysis of code that uses JDK streams API?如何对使用 JDK 流 API 的代码进行渐近分析?
【发布时间】:2018-10-13 04:02:50
【问题描述】:

总的来说,我知道我们必须查看源代码才能了解代码的性能。

但更具体地说,此代码在竞争性编程网站中超时。

这会查找流中从0100 的数字出现的频率。 数组中的数字介于0100 之间。

    // Times out with int[] array containing 100000 elements.

    List<Integer> l = new ArrayList<>();
    for( int i = 0 ; i < array.length ; i ++){
        l.add(array[i]);
    }

    int[] counts = new int[100];
    Arrays.stream(array).forEach( i -> counts[i] = Collections.frequency( l, i));

此代码的 Big-O 分析是什么?我认为罪魁祸首是我使用 Streams API 的方式。

【问题讨论】:

    标签: java java-stream complexity-theory


    【解决方案1】:

    此代码的 Big-O 分析是什么?

    • 没有理由认为Arrays.stream() 本身的成本会随着问题的大小而增加。
    • Stream.forEach()n * K 为界,其中 n 是数组的大小, K 是 lambda 的渐近复杂度。您的特定用途不会缩短迭代,因此没有理由期望更严格的界限
    • lambda 的复杂性由Collections.frequency() 驱动,它与集合的大小成线性关系,也 n,因为它必须扫描整个事物。

    那么,总体而言,这使得 O(n2)。

    这里的浪费是为每个数组元素扫描整个集合。由于您希望每个值平均出现 1000 次,因此成本非常高,并且会随数组元素的数量而变化。我怀疑您打算对count 中的每个位置只扫描一次,但即使这样也会非常浪费。你能想出一种一次性收集频率计数的方法吗?提示:不要想太多。

    【讨论】:

    • 您可能暗示简单的for 循环或Arrays.stream(arr).forEach( i -&gt; counts[i] = counts[i] + 1); 应该更好,我能知道您为什么认为Array.stream 无法扩展吗?
    • @MohanRadhakrishnan,是的,您在评论中描述的方法就是我的想法。它的效率是 O(n),对于这个问题,你不会做得比这更好。当我说Arrays.stream() 不会随着问题的大小而扩展时,我的意思是调用该方法会花费O(1),就像Collection.iterator() 的典型实现一样。它设置了一个Stream 对象,但它不必执行任何每个元素的工作。
    【解决方案2】:

    您正在迭代array(大小为 100000)的所有元素,而您需要做的就是在您创建的列表中找到数字 0 到 100(假设是唯一的)的频率,因此迭代 100有效时间为:

    int[] counts = new int[100];
    IntStream.range(0,100).forEach(i -> counts[i] = Collections.frequency(l,i));
    

    顺便说一句,如果您要遍历整个数组以将其转换为列表,那么更简单的方法是计算同一循环中元素的出现次数。

    int[] counts = new int[100];
    for( int i = 0 ; i < array.length ; i ++){
        counts[array[i]]++; // same asssumption (array[i] < 100)
    }
    

    或以流的形式表示

    Arrays.stream(array).forEach(i -> counts[i]++);
    

    【讨论】:

      猜你喜欢
      • 2018-11-03
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-28
      • 2011-11-11
      • 2021-09-21
      • 1970-01-01
      相关资源
      最近更新 更多