Skip to content
This repository was archived by the owner on Jun 18, 2026. It is now read-only.

Commit 64e9920

Browse files
perf: reuse prev snapshot map in getMigrationCounts and single-pass getSummary
- getMigrationCounts: carry forward previous iteration's currNodeComm as next iteration's prevNodeComm, reducing buildNodeCommunityMap calls from 2*(k-1) to k for k snapshots - getSummary: compute event counts, stability score, and volatility score in a single pass over events using EnumMap, replacing 4 separate stream traversals (getEventCounts + getStabilityScore + getVolatilityScore)
1 parent 8da64a1 commit 64e9920

1 file changed

Lines changed: 28 additions & 4 deletions

File tree

Gvisual/src/gvisual/CommunityEvolutionTracker.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -588,8 +588,13 @@ public double getVolatilityScore() {
588588
*/
589589
public Map<String, Integer> getMigrationCounts() {
590590
Map<String, Integer> migrations = new HashMap<>();
591+
if (snapshots.size() < 2) return migrations;
592+
593+
// Reuse the previous iteration's "curr" map as the next iteration's
594+
// "prev" map, reducing buildNodeCommunityMap calls from 2*(k-1) to k.
595+
Map<String, Set<String>> prevNodeComm = buildNodeCommunityMap(snapshots.get(0));
596+
591597
for (int i = 1; i < snapshots.size(); i++) {
592-
Map<String, Set<String>> prevNodeComm = buildNodeCommunityMap(snapshots.get(i - 1));
593598
Map<String, Set<String>> currNodeComm = buildNodeCommunityMap(snapshots.get(i));
594599

595600
Set<String> allNodes = new HashSet<>(prevNodeComm.keySet());
@@ -605,6 +610,8 @@ public Map<String, Integer> getMigrationCounts() {
605610
}
606611
}
607612
}
613+
614+
prevNodeComm = currNodeComm;
608615
}
609616
return migrations;
610617
}
@@ -626,16 +633,33 @@ public String getSummary() {
626633
sb.append(String.format("Snapshots: %d\n", snapshots.size()));
627634
sb.append(String.format("Total events: %d\n", events.size()));
628635

629-
Map<EventType, Long> counts = getEventCounts();
636+
// Single pass over events to compute counts, stability, and volatility
637+
// instead of 4 separate stream traversals.
638+
Map<EventType, Long> counts = new EnumMap<>(EventType.class);
639+
long stableCount = 0;
640+
long nonLifecycleCount = 0;
641+
long structuralCount = 0;
642+
for (EvolutionEvent e : events) {
643+
EventType t = e.getType();
644+
counts.merge(t, 1L, Long::sum);
645+
if (t != EventType.BIRTH && t != EventType.DEATH) nonLifecycleCount++;
646+
if (t == EventType.STABLE) stableCount++;
647+
if (t == EventType.MERGE || t == EventType.SPLIT
648+
|| t == EventType.BIRTH || t == EventType.DEATH) structuralCount++;
649+
}
630650
for (EventType type : EventType.values()) {
631651
long count = counts.getOrDefault(type, 0L);
632652
if (count > 0) {
633653
sb.append(String.format(" %-12s: %d\n", type, count));
634654
}
635655
}
636656

637-
sb.append(String.format("Stability score: %.2f\n", getStabilityScore()));
638-
sb.append(String.format("Volatility score: %.2f\n", getVolatilityScore()));
657+
double stability = nonLifecycleCount == 0 ? 1.0
658+
: (double) stableCount / nonLifecycleCount;
659+
double volatility = events.isEmpty() ? 0.0
660+
: (double) structuralCount / events.size();
661+
sb.append(String.format("Stability score: %.2f\n", stability));
662+
sb.append(String.format("Volatility score: %.2f\n", volatility));
639663

640664
// Snapshot progression
641665
sb.append("\nSnapshot progression:\n");

0 commit comments

Comments
 (0)