避免在循环中使用两个 AtomicInteger Java
Avoiding usage of two AtomicInteger in a loop Java
我希望 read/write 一个数组(并更新另一个数组)parallelStream
,没有索引。
AtomicInteger
不允许按位运算,使用j.get() * 2
很慢:
final int[] j = {0};
ps.parallelStream().forEach(p -> {
long k = next[j[0] << 1];
for(; k < finalK; k += p)
seg[(int) (k >>> S)] |= (1L << (k & BMASK));
next[j[0] << 1] = (k - finalK);
k = next[j[0] << 1 | 1];
for(; k < finalK; k+= p)
seg[(int) (k >>> S)] |= (1L << (k & BMASK));
next[j[0] << 1 | 1] = (k - finalK);
j[0]++;
});
这是在顺序流中工作,而不是并行。
抱歉,如果 seg[(int) (k >>> S)] |= (1L << (k & BMASK));
看起来不可读,这与设置 BitSet 的位 k 相同(seg 是一个 long[]),这对我来说太慢了。
使用丑陋的 ConcurrentHashMap<Long, Long[]>
避免索引
解决
next.replaceAll((p, k)->{
for(; k[0] < finalK; k[0] += p)
seg[(int) (k[0] >>> S)] |= (1L << (k[0] & BMASK));
for(; k[1] < finalK; k[1] += p)
seg[(int) (k[1] >>> S)] |= (1L << (k[1] & BMASK));
return new long[]{k[0]-finalK, k[1]-finalK});
});
但这很慢,而且会占用更多内存
编辑
为了清楚起见,我使用了一些 indexPairs class 而不是数组和 BitSet
改进了一些东西
ConcurrentHashMap<Long, indexPairs> next = initNext();
BitSet segment = new BitSet();
while(condition) {
next.replaceAll((p, k) -> {
for (; k.low < finalK; k.low += p)
segment.set(k.low);
k.low -= finalK;
for (; k.high < finalK; k.high += p)
segment.set(k.high);
k.high -= finalK;
return k;
});
... Do something with segment
}
我希望 read/write 一个数组(并更新另一个数组)parallelStream
,没有索引。
AtomicInteger
不允许按位运算,使用j.get() * 2
很慢:
final int[] j = {0};
ps.parallelStream().forEach(p -> {
long k = next[j[0] << 1];
for(; k < finalK; k += p)
seg[(int) (k >>> S)] |= (1L << (k & BMASK));
next[j[0] << 1] = (k - finalK);
k = next[j[0] << 1 | 1];
for(; k < finalK; k+= p)
seg[(int) (k >>> S)] |= (1L << (k & BMASK));
next[j[0] << 1 | 1] = (k - finalK);
j[0]++;
});
这是在顺序流中工作,而不是并行。
抱歉,如果 seg[(int) (k >>> S)] |= (1L << (k & BMASK));
看起来不可读,这与设置 BitSet 的位 k 相同(seg 是一个 long[]),这对我来说太慢了。
使用丑陋的 ConcurrentHashMap<Long, Long[]>
避免索引
next.replaceAll((p, k)->{
for(; k[0] < finalK; k[0] += p)
seg[(int) (k[0] >>> S)] |= (1L << (k[0] & BMASK));
for(; k[1] < finalK; k[1] += p)
seg[(int) (k[1] >>> S)] |= (1L << (k[1] & BMASK));
return new long[]{k[0]-finalK, k[1]-finalK});
});
但这很慢,而且会占用更多内存
编辑
为了清楚起见,我使用了一些 indexPairs class 而不是数组和 BitSet
改进了一些东西
ConcurrentHashMap<Long, indexPairs> next = initNext();
BitSet segment = new BitSet();
while(condition) {
next.replaceAll((p, k) -> {
for (; k.low < finalK; k.low += p)
segment.set(k.low);
k.low -= finalK;
for (; k.high < finalK; k.high += p)
segment.set(k.high);
k.high -= finalK;
return k;
});
... Do something with segment
}