RED-7141: Performance improvments
This commit is contained in:
parent
cb9127b4f3
commit
d659fe7234
@ -77,9 +77,9 @@ public class Character {
|
|||||||
public double angle(Character character) {
|
public double angle(Character character) {
|
||||||
|
|
||||||
if (getX() > character.getX()) {
|
if (getX() > character.getX()) {
|
||||||
return FastAtan2.atan2(getY() - character.getY(), getX() - character.getX());
|
return FastAtan2.fastAtan2(getY() - character.getY(), getX() - character.getX());
|
||||||
} else {
|
} else {
|
||||||
return FastAtan2.atan2(character.getY() - getY(), character.getX() - getX());
|
return FastAtan2.fastAtan2(character.getY() - getY(), character.getX() - getX());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,7 @@ public class Neighbor {
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final double distance;
|
private final double distance;
|
||||||
@Getter
|
private Double angle;
|
||||||
private final double angle;
|
|
||||||
private final Character originCharacter;
|
private final Character originCharacter;
|
||||||
@Getter
|
@Getter
|
||||||
private final Character character;
|
private final Character character;
|
||||||
@ -16,7 +15,6 @@ public class Neighbor {
|
|||||||
public Neighbor(Character neighbor, Character origin) {
|
public Neighbor(Character neighbor, Character origin) {
|
||||||
|
|
||||||
this.distance = neighbor.distance(origin);
|
this.distance = neighbor.distance(origin);
|
||||||
this.angle = neighbor.angle(origin);
|
|
||||||
this.character = neighbor;
|
this.character = neighbor;
|
||||||
this.originCharacter = origin;
|
this.originCharacter = origin;
|
||||||
}
|
}
|
||||||
@ -33,4 +31,13 @@ public class Neighbor {
|
|||||||
return character.verticalDistance(originCharacter);
|
return character.verticalDistance(originCharacter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public double getAngle() {
|
||||||
|
|
||||||
|
if (angle != null) {
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
return this.character.angle(this.originCharacter);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -31,8 +31,9 @@ public class NearestNeighbourService {
|
|||||||
|
|
||||||
for (int i = 0; i < characters.size(); i++) {
|
for (int i = 0; i < characters.size(); i++) {
|
||||||
|
|
||||||
List<Neighbor> candidates = new ArrayList<>();
|
Neighbor[] candidates = new Neighbor[maxNeighborCount + 1];
|
||||||
|
int neighborInsertionIndex = 0;
|
||||||
|
int neighborCount = 0;
|
||||||
int start = i;
|
int start = i;
|
||||||
int end = i + 1;
|
int end = i + 1;
|
||||||
|
|
||||||
@ -45,42 +46,83 @@ public class NearestNeighbourService {
|
|||||||
|
|
||||||
while (start > 0 && characters.get(i).getX() - characters.get(start - 1).getX() < searchDistance) {
|
while (start > 0 && characters.get(i).getX() - characters.get(start - 1).getX() < searchDistance) {
|
||||||
start--;
|
start--;
|
||||||
candidates.add(new Neighbor(characters.get(start), characters.get(i)));
|
candidates[neighborInsertionIndex] = new Neighbor(characters.get(start), characters.get(i));
|
||||||
clearMostDistant(candidates, maxNeighborCount);
|
neighborCount++;
|
||||||
|
if (neighborCount > maxNeighborCount) {
|
||||||
|
neighborInsertionIndex = clearMostDistant(candidates);
|
||||||
|
neighborCount--;
|
||||||
|
} else {
|
||||||
|
neighborInsertionIndex++;
|
||||||
|
}
|
||||||
newCandidatesFound = true;
|
newCandidatesFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (end < characters.size() && characters.get(end).getX() - characters.get(i).getX() < searchDistance) {
|
while (end < characters.size() && characters.get(end).getX() - characters.get(i).getX() < searchDistance) {
|
||||||
candidates.add(new Neighbor(characters.get(end), characters.get(i)));
|
candidates[neighborInsertionIndex] = new Neighbor(characters.get(end), characters.get(i));
|
||||||
clearMostDistant(candidates, maxNeighborCount);
|
neighborCount++;
|
||||||
|
if (neighborCount > maxNeighborCount) {
|
||||||
|
neighborInsertionIndex = clearMostDistant(candidates);
|
||||||
|
neighborCount--;
|
||||||
|
} else {
|
||||||
|
neighborInsertionIndex++;
|
||||||
|
}
|
||||||
end++;
|
end++;
|
||||||
newCandidatesFound = true;
|
newCandidatesFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newCandidatesFound && candidates.size() >= maxNeighborCount) {
|
if (newCandidatesFound && neighborCount >= maxNeighborCount) {
|
||||||
distance = candidates.stream().mapToDouble(Neighbor::getDistance).max().orElse(Double.POSITIVE_INFINITY);
|
distance = maxDistance(candidates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clearMostDistant(candidates, maxNeighborCount);
|
if (neighborCount < maxNeighborCount) {
|
||||||
characters.get(i).setNeighbors(new ArrayList<>(candidates));
|
clearMostDistant(candidates);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Neighbor> candidatesList = new ArrayList<>(maxNeighborCount);
|
||||||
|
for (Neighbor candidate : candidates) {
|
||||||
|
if (candidate != null) {
|
||||||
|
candidatesList.add(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
candidatesList.sort(Comparator.comparingDouble(Neighbor::getDistance));
|
||||||
|
assert candidatesList.size() == maxNeighborCount;
|
||||||
|
characters.get(i).setNeighbors(candidatesList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void clearMostDistant(List<Neighbor> candidates, int maxNeighborCount) {
|
private double maxDistance(Neighbor[] candidates) {
|
||||||
|
|
||||||
if (candidates.size() > maxNeighborCount) {
|
double maxDistance = 0;
|
||||||
double maxDistance = 0;
|
for (Neighbor candidate : candidates) {
|
||||||
int maxIndex = 0;
|
if (candidate == null) {
|
||||||
for (int i = 0; i < candidates.size(); i++) {
|
continue;
|
||||||
Neighbor candidate = candidates.get(i);
|
}
|
||||||
if (candidate.getDistance() > maxDistance) {
|
if (candidate.getDistance() > maxDistance) {
|
||||||
maxDistance = candidate.getDistance();
|
maxDistance = candidate.getDistance();
|
||||||
maxIndex = i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
candidates.remove(maxIndex);
|
|
||||||
}
|
}
|
||||||
|
return maxDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int clearMostDistant(Neighbor[] candidates) {
|
||||||
|
|
||||||
|
double maxDistance = 0;
|
||||||
|
int maxIndex = 0;
|
||||||
|
for (int i = 0; i < candidates.length; i++) {
|
||||||
|
Neighbor candidate = candidates[i];
|
||||||
|
if (candidate == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (candidate.getDistance() > maxDistance) {
|
||||||
|
maxDistance = candidate.getDistance();
|
||||||
|
maxIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
candidates[maxIndex] = null;
|
||||||
|
return maxIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ public class FastAtan2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ParameterAssignment")
|
@SuppressWarnings("ParameterAssignment")
|
||||||
static public double atan2(double y, double x) {
|
static public double fastAtan2(double y, double x) {
|
||||||
|
|
||||||
if (y < 0) {
|
if (y < 0) {
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
|
|||||||
@ -33,8 +33,8 @@ public class ViewerDocumentTest extends BuildDocumentTest {
|
|||||||
ViewerDocumentService viewerDocumentService = new ViewerDocumentService(null);
|
ViewerDocumentService viewerDocumentService = new ViewerDocumentService(null);
|
||||||
LayoutGridService layoutGridService = new LayoutGridService(viewerDocumentService);
|
LayoutGridService layoutGridService = new LayoutGridService(viewerDocumentService);
|
||||||
|
|
||||||
Document document = buildGraph(fileName, LayoutParsingType.REDACT_MANAGER);
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
Document document = buildGraph(fileName, LayoutParsingType.REDACT_MANAGER);
|
||||||
layoutGridService.addLayoutGrid(documentFile, document, new File(tmpFileName), true);
|
layoutGridService.addLayoutGrid(documentFile, document, new File(tmpFileName), true);
|
||||||
System.out.printf("Total time: %.2fs%n", ((float) (System.currentTimeMillis() - start)) / 1000);
|
System.out.printf("Total time: %.2fs%n", ((float) (System.currentTimeMillis() - start)) / 1000);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user