Java 使用流实现最佳性能的嵌套循环

Java 使用流实现最佳性能的嵌套循环,java,java-8,java-stream,Java,Java 8,Java Stream,我开始学习Java8的特性,特别是streams和Lambda,我很困惑。 我试图重写下面的代码 MyClass graph = new MyClass(V); for (int i = 0; i < numOfVertices; i++) { for (int j = 0; j < numOfVertices; j++) { if (adjMatrix[i][j] != 0) { graph.addEdge(i, j, adjMatrix[i]

我开始学习Java8的特性,特别是streams和Lambda,我很困惑。 我试图重写下面的代码

MyClass graph = new MyClass(V);

for (int i = 0; i < numOfVertices; i++) {
   for (int j = 0; j < numOfVertices; j++) {
      if (adjMatrix[i][j] != 0) {
         graph.addEdge(i, j, adjMatrix[i][j]);
      }
   }
}
当然不行了。重写上述代码的正确方法是什么?我也在寻找最好的性能,所以我尝试使用并行方法


谢谢

无论性能如何,这都是一个用流重写的简单表单:

                IntStream.range(0, numOfVertices - 1)
                 .forEach(i -> IntStream.range(0, numOfVertices - 1)
                   .filter(j -> adjMatrix[i][j] != 0)
                     .forEach(j -> graph.addEdge(i, j, adjMatrix[i][j])));
简短回答

如果你想要“最佳性能”,迭代中的时间越短:对于小矩阵使用“for循环”,对于更大的情况,你可以考虑使用“并行流”< /P> .. 长话短说 我创建了一个测试来测量三个选项之一的平均执行时间

“用于循环:”

for(int i=0;i
“IntStream.range:”

IntStream.range(0,大小)
.forEach(i->(IntStream.range(0,大小))
.forEach(j->{
doSomething(numoftexts[i][j]);
}));
“IntStream.range并行:”

IntStream.range(0,size.parallel)()
.forEach(i->(IntStream.range(0,大小))
.forEach(j->{
doSomething(numoftexts[i][j]);
}));
此部分已删除,因为我无法模拟其时间成本:

if(调整矩阵[i][j]!=0){
图.加法(i,j,调整矩阵[i][j]);
}
下面是对不同矩阵执行测量的整个测试代码。 每个案例运行10000次,并给出平均时间。 这是在我的计算机上运行的结果。对于小矩阵(1 x 1到100 x 100),For loop是最佳选择。当矩阵较大(大于500 x 500)时,使用“IntStream.range并行”会更快。对于每种情况,“IntStream.range”总是比“For循环”更糟糕

Size: 1
IntStream.range parallel: 0.002300
         IntStream.range: 0.002200
                For loop: 0.000000
Size: 5
IntStream.range parallel: 0.023000
         IntStream.range: 0.000500
                For loop: 0.000000
Size: 10
IntStream.range parallel: 0.025800
         IntStream.range: 0.000300
                For loop: 0.000100
Size: 50
IntStream.range parallel: 0.042200
         IntStream.range: 0.004300
                For loop: 0.000900
Size: 100
IntStream.range parallel: 0.035000
         IntStream.range: 0.006000
                For loop: 0.004300
Size: 500
IntStream.range parallel: 0.060200
         IntStream.range: 0.102000
                For loop: 0.079600
Size: 1000
IntStream.range parallel: 0.122000
         IntStream.range: 0.379800
                For loop: 0.347400
publicstaticvoidmain(字符串[]args){
数组.asList(1,5,10,501005001000).forEach(
尺寸->{
System.out.println(“尺寸:+尺寸”);
整数[][]numoftexts=createArray(大小);
Map toRun=Map.of(
“For循环:”,
() -> {
对于(int i=0;i {
IntStream.range(0,大小)
.forEach(i->(IntStream.range(0,大小))
.forEach(j->{
doSomething(numoftexts[i][j]);
}));
},
“IntStream.range并行:”,
() -> {
IntStream.range(0,大小).parallel()
.forEach(i->(IntStream.range(0,大小))
.forEach(j->{
doSomething(numoftexts[i][j]);
}));
}
);
int howManyTimes=10000;
Map Map=newhashmap();
toRun.entrySet().forEach(e->{
double time=(((double)IntStream.range(0,howManyTimes.mapToObj)(
(x) ->执行时间(如getValue())
.reduce(Long::sum).get()/howManyTimes);
put(例如getKey(),time);
});
map.entrySet().forEach(e->{
System.out.println(String.format(“%25s%f”,e.getKey(),e.getValue());
});
}
);
}
私有静态整数[][]createArray(整数大小){
整数[][]val=新整数[size][size];
IntStream.range(0,size).forEach(
i->IntStream.range(0,size).forEach(
j->val[i][j]=(int)(Math.random()*100)
)
);
返回val;
}
专用静态int-doSomething(int-val){
返回val*val;
}
私有静态长执行时间(Runnable ExecutionThis)
{
long startTime=System.currentTimeMillis();
execThis.run();
long-endTime=System.currentTimeMillis();
返回(结束时间开始时间);
}

“当然不行”-请提供更多详细信息。是否有错误,或者结果不正确,或者其他什么?最好是你必须测量的东西;在99%的情况下,坚持使用普通的旧循环。请注意,只有当
图形
对象允许并行更新而不使用锁时,并行化才有意义。我怀疑情况并非如此,除非您的图形数据结构是根据这一要求精心设计的。首先,在转向流时,为什么将
numoftexts
更改为
numoftexts-1
?其次,
graph.addEdge(…)
线程安全吗?你在没有
.parallel()
的情况下测试了吗?这是我的错误,应该是numoftexts。是的,我同意,我完全忽略了内部循环逻辑谢谢你的回答!它按预期工作,但是,正如您所提到的,性能并没有那么好。很抱歉响应太晚,但感谢您用示例进行如此出色的解释!
Size: 1
IntStream.range parallel: 0.002300
         IntStream.range: 0.002200
                For loop: 0.000000
Size: 5
IntStream.range parallel: 0.023000
         IntStream.range: 0.000500
                For loop: 0.000000
Size: 10
IntStream.range parallel: 0.025800
         IntStream.range: 0.000300
                For loop: 0.000100
Size: 50
IntStream.range parallel: 0.042200
         IntStream.range: 0.004300
                For loop: 0.000900
Size: 100
IntStream.range parallel: 0.035000
         IntStream.range: 0.006000
                For loop: 0.004300
Size: 500
IntStream.range parallel: 0.060200
         IntStream.range: 0.102000
                For loop: 0.079600
Size: 1000
IntStream.range parallel: 0.122000
         IntStream.range: 0.379800
                For loop: 0.347400