gpt4 book ai didi

java - 为什么通过 stream() 调用比使用 if 子句更耗时?

转载 作者:行者123 更新时间:2023-12-04 02:30:45 25 4
gpt4 key购买 nike

为什么是这个方法:

public static int howManyDifferentFields() {
int difcolor = 0;
difcolor++;
if (fields[1] != fields[0]) {
difcolor++;
}
if (fields[2] != fields[1] && fields[2] != fields[0]) {
difcolor++;
}
if (fields[3] != fields[2] && fields[3] != fields[1] && fields[3] != fields[0]) {
difcolor++;
}
if (fields[4] != fields[3] && fields[4] != fields[2] && fields[4] != fields[1] && fields[4] != fields[0]) {
difcolor++;
}
if (fields[5] != fields[4] && fields[5] != fields[3] && fields[5] != fields[2] && fields[5] != fields[1] && fields[5] != fields[0]) {
difcolor++;
}
if (fields[6] != fields[5] && fields[6] != fields[4] && fields[6] != fields[3] && fields[6] != fields[2] && fields[6] != fields[1] && fields[6] != fields[0]) {
difcolor++;
}
if (fields[7] != fields[6] && fields[7] != fields[5] && fields[7] != fields[4] && fields[7] != fields[3] && fields[7] != fields[2] && fields[7] != fields[1] && fields[7] != fields[0]) {
difcolor++;
}
if (fields[8] != fields[7] && fields[8] != fields[6] && fields[8] != fields[5] && fields[8] != fields[4] && fields[8] != fields[3] && fields[8] != fields[2] && fields[8] != fields[1] && fields[8] != fields[0]) {
difcolor++;
}
return difcolor;
}

比这还快?

public static int howManyDifferentFields2() {
return (int) Arrays.stream(fields).distinct().count();
}

我想使用第二种方式,因为它的代码少得多。但这需要更多时间!当我使用第二种方法而不是第一种方法时,程序需要大约 8 倍的时间才能完成。我能做些什么?我能以某种方式重写第一个方法使其有效但代码更少吗?在我看来,第二种方法看起来好多了......

最佳答案

大多数人认为流速度很快。但他们不是。有很多代码支持它们,而这正是您遇到的隐藏开销。

在一般情况下,普通 for 循环比非并行流(甚至在元素数量不大时的并行流)更快。

虽然流可以生成简洁而强大的代码并有很多好处,但对于小型流而言,性能并不是其中之一。


你的逻辑有 O(n2) 的时间复杂度,但如果 n 固定为 8 你就没问题,你可以将它重写为这个接近等效的循环:

int difcolor = 8;
for (int i = 1; i < fields.length; i++) {
for (int j = 0; j < i; j++) {
if (fields[i] == fields[j]) {
difcolor--;
break;
}
}
}
return difcolor;

从满分开始然后在第一场比赛中递减提高了效率,因为它通过尽早退出内部循环来减少操作次数,类似于您使用短路 &&

您也可以使用 Set,它具有 O(n) 的时间复杂度并且更紧凑,但只有 8 个元素,它可能比上面的循环慢:

Set<Integer> set = new HashSet<>(); // assuming fields is a int[] 
int difcolor = 0;
for (int field : fields) {
if (set.add(field)) {
difcolor++;
}
}

这与您的流版本的工作方式类似,但没有流开销。

如果元素已排序,您可以一次性完成,只比较邻居。

关于java - 为什么通过 stream() 调用比使用 if 子句更耗时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64356017/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com