针对多个谓词扫描一次数组或针对单个谓词多次扫描数组是否更有效

时间:2018-03-20 07:21:51

标签: java performance sorting

我有一个包含1000个元素的int数组。我需要提取数组中各种子群的大小(有多少是偶数,奇数,大于500等)。

我可以使用for循环和一堆if语句来尝试为每个匹配的项添加计数变量,例如:

for(int i = 0; i < someArray.length i++) {
    if(conditionA) sizeA++;
    if(conditionB) sizeB++;
    if(conditionC) sizeC++;
    ...
}

或者我可以做一些更懒惰的事情,例如:

Supplier<IntStream> ease = () -> Arrays.stream(someArray);
int sizeA = ease.get().filter(conditionA).toArray.length;
int sizeB = ease.get().filter(conditionB).toArray.length;
int sizeC = ease.get().filter(conditionC).toArray.length;
...

以第二种方式实现这一目标的好处似乎仅限于可读性,但效率是否会受到巨大冲击?它可能更有效率吗?我猜它归结为迭代数组一次,4个条件总是好于每次迭代4次,每次一个条件(假设条件是独立的)。我知道这个特殊的例子,第二种方法有很多额外的方法调用,我肯定不会提高效率。

2 个答案:

答案 0 :(得分:3)

序言:

  • 正如@Kayaman指出的那样,对于一个小阵列(1000个元素),它可能并不重要。

  • 这种方法的正确方法是优化 后你有工作代码,工作基准, 后你已经分析了代码,看看真正的热点在哪里。

但是假设这值得花费在优化上,第一​​个版本可能比第二个版本更快,原因有两个:

  1. 递增和测试索引的开销仅在第一个版本中产生一次,而在第二个版本中产生三次。

  2. 对于太大而无法放入内存缓存的数组,第一个版本将比第二个版本需要更少的内存读取。由于内存访问通常是一个瓶颈(特别是在多核机器上),这可能很重要。

  3. 与简单的数组迭代相比,Streams会增加额外的性能开销。

答案 1 :(得分:3)

我用这段代码做了一些测量:

export PYTHONPATH=$SPARK_HOME/python/lib/py4j-0.10.1-src.zip:$PYTHONPATH

以上输出一个8位数字,通常约为14000000

如果我取消注释for循环并对流进行注释,我会得到一个5位数的输出,通常大约为80000。

因此,流的执行时间较慢。

但是,当数组大小较大时,流和循环之间的差异会变小。