From 02380503fec27e396fc97ab4c2faa6a327c7ae27 Mon Sep 17 00:00:00 2001 From: Kilian Schuettler Date: Fri, 8 Mar 2024 09:49:13 +0100 Subject: [PATCH] RED-7141: replaced arrayList with array access --- .../service/NearestNeighbourService.java | 86 ++++++++++++++----- 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/docstrum/service/NearestNeighbourService.java b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/docstrum/service/NearestNeighbourService.java index 4a8338e..78c6fb7 100644 --- a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/docstrum/service/NearestNeighbourService.java +++ b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/docstrum/service/NearestNeighbourService.java @@ -14,6 +14,8 @@ public class NearestNeighbourService { private static final int NUMBER_OF_NEIGHBOURS = 8; private static final double STEP = 16.0; + private int neighborInsertionIndex; + private int neighborCount; public void findNearestNeighbors(List characters) { @@ -31,8 +33,9 @@ public class NearestNeighbourService { for (int i = 0; i < characters.size(); i++) { - List candidates = new ArrayList<>(); - + Neighbor[] candidates = new Neighbor[maxNeighborCount + 1]; + neighborInsertionIndex = 0; + neighborCount = 0; int start = i; int end = i + 1; @@ -45,42 +48,83 @@ public class NearestNeighbourService { while (start > 0 && characters.get(i).getX() - characters.get(start - 1).getX() < searchDistance) { start--; - candidates.add(new Neighbor(characters.get(start), characters.get(i))); - clearMostDistant(candidates, maxNeighborCount); + candidates[neighborInsertionIndex] = new Neighbor(characters.get(start), characters.get(i)); + neighborCount++; + if (neighborCount > maxNeighborCount) { + neighborInsertionIndex = clearMostDistant(candidates); + neighborCount--; + } else { + neighborInsertionIndex++; + } newCandidatesFound = true; } while (end < characters.size() && characters.get(end).getX() - characters.get(i).getX() < searchDistance) { - candidates.add(new Neighbor(characters.get(end), characters.get(i))); - clearMostDistant(candidates, maxNeighborCount); + candidates[neighborInsertionIndex] = new Neighbor(characters.get(end), characters.get(i)); + neighborCount++; + if (neighborCount > maxNeighborCount) { + neighborInsertionIndex = clearMostDistant(candidates); + neighborCount--; + } else { + neighborInsertionIndex++; + } end++; newCandidatesFound = true; } - if (newCandidatesFound && candidates.size() >= maxNeighborCount) { - distance = candidates.stream().mapToDouble(Neighbor::getDistance).max().orElse(Double.POSITIVE_INFINITY); + if (newCandidatesFound && neighborCount >= maxNeighborCount) { + distance = maxDistance(candidates); } } - clearMostDistant(candidates, maxNeighborCount); - characters.get(i).setNeighbors(new ArrayList<>(candidates)); + if (neighborCount < maxNeighborCount) { + clearMostDistant(candidates); + neighborCount--; + } + + List 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 candidates, int maxNeighborCount) { + private double maxDistance(Neighbor[] candidates) { - if (candidates.size() > maxNeighborCount) { - double maxDistance = 0; - int maxIndex = 0; - for (int i = 0; i < candidates.size(); i++) { - Neighbor candidate = candidates.get(i); - if (candidate.getDistance() > maxDistance) { - maxDistance = candidate.getDistance(); - maxIndex = i; - } + double maxDistance = 0; + for (Neighbor candidate : candidates) { + if (candidate == null) { + continue; + } + if (candidate.getDistance() > maxDistance) { + maxDistance = candidate.getDistance(); } - 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; } }