我有一个包含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次,每次一个条件(假设条件是独立的)。我知道这个特殊的例子,第二种方法有很多额外的方法调用,我肯定不会提高效率。
答案 0 :(得分:3)
序言:
正如@Kayaman指出的那样,对于一个小阵列(1000个元素),它可能并不重要。
这种方法的正确方法是优化 后你有工作代码,工作基准, 后你已经分析了代码,看看真正的热点在哪里。
但是假设这值得花费在优化上,第一个版本可能比第二个版本更快,原因有两个:
递增和测试索引的开销仅在第一个版本中产生一次,而在第二个版本中产生三次。
对于太大而无法放入内存缓存的数组,第一个版本将比第二个版本需要更少的内存读取。由于内存访问通常是一个瓶颈(特别是在多核机器上),这可能很重要。
与简单的数组迭代相比,Streams会增加额外的性能开销。
答案 1 :(得分:3)
我用这段代码做了一些测量:
export PYTHONPATH=$SPARK_HOME/python/lib/py4j-0.10.1-src.zip:$PYTHONPATH
以上输出一个8位数字,通常约为14000000
如果我取消注释for循环并对流进行注释,我会得到一个5位数的输出,通常大约为80000。
因此,流的执行时间较慢。
但是,当数组大小较大时,流和循环之间的差异会变小。