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.ArrayDeque;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.IntStream;
|
import java.util.PrimitiveIterator;
|
||||||
|
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@ -313,14 +315,31 @@ public class Equihash {
|
||||||
overspillMultimap = MultimapBuilder.hashKeys().arrayListValues().build();
|
overspillMultimap = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
IntStream get(int key) {
|
PrimitiveIterator.OfInt get(int key) {
|
||||||
if (shortLists[key * 4 + 3] == 0) {
|
return new PrimitiveIterator.OfInt() {
|
||||||
return IntStream.range(0, 4).map(i -> ~shortLists[key * 4 + i]).takeWhile(i -> i >= 0);
|
int i;
|
||||||
}
|
Iterator<Integer> overspillIterator;
|
||||||
return IntStream.concat(
|
|
||||||
IntStream.range(0, 4).map(i -> ~shortLists[key * 4 + i]),
|
private Iterator<Integer> overspillIterator() {
|
||||||
overspillMultimap.get(key).stream().mapToInt(i -> i)
|
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:
|
// assumes non-negative values only:
|
||||||
|
@ -347,18 +366,18 @@ public class Equihash {
|
||||||
for (int i = 0; i < table.numRows; i++) {
|
for (int i = 0; i < table.numRows; i++) {
|
||||||
var row = table.getRow(i);
|
var row = table.getRow(i);
|
||||||
var collisionIndices = indexMultimap.get(row.get(0));
|
var collisionIndices = indexMultimap.get(row.get(0));
|
||||||
collisionIndices.forEach(ii -> {
|
while (collisionIndices.hasNext()) {
|
||||||
var collidingRow = table.getRow(ii);
|
var collidingRow = table.getRow(collisionIndices.nextInt());
|
||||||
if (isPartial) {
|
if (isPartial) {
|
||||||
for (int j = 1; j < table.hashWidth; j++) {
|
for (int j = 1; j < table.hashWidth; j++) {
|
||||||
newTableValues.add(collidingRow.get(j) ^ row.get(j));
|
newTableValues.add(collidingRow.get(j) ^ row.get(j));
|
||||||
}
|
}
|
||||||
} else if (!collidingRow.subArray(1, table.hashWidth).equals(row.subArray(1, table.hashWidth))) {
|
} 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(collidingRow.subArray(table.hashWidth, collidingRow.length()));
|
||||||
newTableValues.addAll(row.subArray(table.hashWidth, row.length()));
|
newTableValues.addAll(row.subArray(table.hashWidth, row.length()));
|
||||||
});
|
}
|
||||||
indexMultimap.put(row.get(0), i);
|
indexMultimap.put(row.get(0), i);
|
||||||
}
|
}
|
||||||
return new XorTable(newHashWidth, newIndexTupleWidth, newTableValues.build());
|
return new XorTable(newHashWidth, newIndexTupleWidth, newTableValues.build());
|
||||||
|
|
Loading…
Add table
Reference in a new issue