我想迭代2D数组中单元格的邻居。所以我用:
for(var i=0; i<list.length; i++){
console.log(list[i].main.temp);
}
我的问题是,如果这是最有效的方式,还是更好地使用if电话?如果有一个比使用它更好的方法,如果在循环内摆脱零零情况?
答案 0 :(得分:2)
尚未对其进行测试,但以下是基于@ Zefick的答案,应该更高效:
int dirs[] = { -1, -1, -1, 0, -1, 1, 0, -1, 0, 1, 1, -1, 1, 0, 1, 1 };
for (int i = 0; i < dirs.length; i += 2) {
int xOffset = dirs[i];
int yOffset = dirs[i + 1];
// my code
}
答案 1 :(得分:2)
我运行了一个JMH基准测试,提供了各种解决方案。我总是在黑洞中消耗2个偏移量。结果如下:
Benchmark Mode Cnt Score Error Units
Offset2DBenchmark.doubleLoopWithIf thrpt 3 35425373,827 ± 4242716,439 ops/s
Offset2DBenchmark.loopOverFlatIndex thrpt 3 35929636,197 ± 935681,592 ops/s
Offset2DBenchmark.loopOverIndex thrpt 3 31438051,279 ± 3286314,668 ops/s
Offset2DBenchmark.unrolledLoop thrpt 3 40495297,238 ± 6423961,118 ops/s
Offset2DBenchmark.unrolledLoopWithLambda thrpt 3 27526581,417 ± 1712524,060 ops/s
doubleLoopWithIf = Nested Loops with If to filter 0,0 (TheSorm)
loopOverFlatIndex = Single loop with flattend indizes (Oleg)
loopOverIndex = Single Loop with 2d indizes (Zefick)
unrolledLoop = Completely Unrolled Loop
unrolledLoopWithLambda = Unrolled Loop consuming a Bifunction<Integer, Integer>
因此,展开的循环是最快的。稍微慢一点的是带有if语句和Oleg提出的扁平数组的双循环。 Zefick的2D阵列比你的解决方案更慢。
就像演示一样,这是测试的样子:
@Fork(value = 1)
@Warmup(iterations = 3)
@Measurement(iterations = 3)
@Benchmark
public void unrolledLoopWithLambda(Blackhole bh) {
outerOffsets((x, y) -> {
bh.consume(x);
bh.consume(y);
});
}
private void outerOffsets(BiConsumer<Integer, Integer> consumer) {
consumer.accept(-1, -1);
consumer.accept(-1, 0);
consumer.accept(-1, 1);
consumer.accept(0, -1);
consumer.accept(0, 1);
consumer.accept(1, -1);
consumer.accept(1, 0);
consumer.accept(1, 1);
}
因此,除非您想手动展开循环,否则您无法提高性能。
不幸的是,你并没有告诉你循环中的代码是什么样的。如果它甚至有点耗费时间,你如何循环的问题可能是可以忽略的......
但是你的标题声明你希望这个作为二维数组的偏移量。我怀疑你可能会在 x 和 y 的更大循环中使用它。您可以通过使用1d数组并自己计算索引来获得更高的性能。
而不是:
array[x][y]
使用
array[xy] with xy = x + y * xsize
你应该能够避免进行乘法运算。
(这是我第一次使用JMH运行基准测试,所以请告诉我是否使用它完全错误...)
答案 2 :(得分:1)
我通常使用以下方法:
int dirs[][] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};
for (int dir[] : dirs) {
int xOffset = dir[0];
int yOffset = dir[1];
// my code
}