我跑了江鈴控股基準用這個問題的各種解決方案。我總是在黑洞中消耗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的二維數組比您的解決方案更慢。
就像一個演示,這裏是一個測試看起來像什麼:
@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
你應該能夠避免做乘法的。
(這是我第一次跑了標杆與江鈴控股,所以請告訴我,如果我用它完全錯了...)
你認爲什麼是最可讀性和可維護性的解決方案?這裏是否存在實際的性能問題? – tnw
是的它是一種性能問題,我尋找所有我可以優化的東西。這是在數百萬個對象的更新循環中運行的。 – TheSorm
因此,使用您當前的解決方案的性能是否存在實際問題? – tnw