mirror of
https://github.com/bisq-network/bisq.git
synced 2025-03-04 03:03:48 +01:00
Further Equihash optimisation: avoid lambda+stream in tight loop
Manually iterate over colliding table rows using a while- loop and a custom 'PrimitiveIterator.OfInt' implementation, instead of a foreach lambda called on an IntStream, in 'Equihash::findCollisions'. Profiling shows that this results in a slight speedup.
This commit is contained in:
parent
3130d9329c
commit
0a603167f1
1 changed files with 32 additions and 13 deletions
|
@ -38,8 +38,10 @@ import java.math.BigInteger;
|
|||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.PrimitiveIterator;
|
||||
|
||||
import lombok.ToString;
|
||||
|
||||
|
@ -313,14 +315,31 @@ public class Equihash {
|
|||
overspillMultimap = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||
}
|
||||
|
||||
IntStream get(int key) {
|
||||
if (shortLists[key * 4 + 3] == 0) {
|
||||
return IntStream.range(0, 4).map(i -> ~shortLists[key * 4 + i]).takeWhile(i -> i >= 0);
|
||||
}
|
||||
return IntStream.concat(
|
||||
IntStream.range(0, 4).map(i -> ~shortLists[key * 4 + i]),
|
||||
overspillMultimap.get(key).stream().mapToInt(i -> i)
|
||||
);
|
||||
PrimitiveIterator.OfInt get(int key) {
|
||||
return new PrimitiveIterator.OfInt() {
|
||||
int i;
|
||||
Iterator<Integer> overspillIterator;
|
||||
|
||||
private Iterator<Integer> overspillIterator() {
|
||||
if (overspillIterator == null) {
|
||||
overspillIterator = overspillMultimap.get(i).iterator();
|
||||
}
|
||||
return overspillIterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextInt() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
return i < 4 ? ~shortLists[key * 4 + i++] : overspillIterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return i < 4 && shortLists[key * 4 + i] < 0 || i == 4 && overspillIterator().hasNext();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// assumes non-negative values only:
|
||||
|
@ -347,18 +366,18 @@ public class Equihash {
|
|||
for (int i = 0; i < table.numRows; i++) {
|
||||
var row = table.getRow(i);
|
||||
var collisionIndices = indexMultimap.get(row.get(0));
|
||||
collisionIndices.forEach(ii -> {
|
||||
var collidingRow = table.getRow(ii);
|
||||
while (collisionIndices.hasNext()) {
|
||||
var collidingRow = table.getRow(collisionIndices.nextInt());
|
||||
if (isPartial) {
|
||||
for (int j = 1; j < table.hashWidth; j++) {
|
||||
newTableValues.add(collidingRow.get(j) ^ row.get(j));
|
||||
}
|
||||
} else if (!collidingRow.subArray(1, table.hashWidth).equals(row.subArray(1, table.hashWidth))) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
newTableValues.addAll(collidingRow.subArray(table.hashWidth, collidingRow.length()));
|
||||
newTableValues.addAll(row.subArray(table.hashWidth, row.length()));
|
||||
});
|
||||
}
|
||||
indexMultimap.put(row.get(0), i);
|
||||
}
|
||||
return new XorTable(newHashWidth, newIndexTupleWidth, newTableValues.build());
|
||||
|
|
Loading…
Add table
Reference in a new issue