From eb0d1ca36e9d359443d35188a741fe427d85d292 Mon Sep 17 00:00:00 2001 From: Ronak Buch Date: Wed, 15 Sep 2021 23:25:07 -0400 Subject: [PATCH] Only use Entry ID<->index maps if necessary In the common case, Entry IDs and indices are both contiguous and start from 0, so these maps are just the identity function. ID->index conversion is on the hot path for drawing Timeline and the boxing/unboxing and map lookup can be relatively costly, so avoid it when possible. --- src/projections/analysis/StsReader.java | 48 +++++++++++++++++-------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/projections/analysis/StsReader.java b/src/projections/analysis/StsReader.java index 3155d71..c21e474 100644 --- a/src/projections/analysis/StsReader.java +++ b/src/projections/analysis/StsReader.java @@ -80,9 +80,9 @@ public String toString() { /** index by Integer ID in STS file, return String name */ public Map entryChares = new TreeMap(); /** keys are indexes into flat arrays, values are the IDs given in STS file */ - private Map entryFlatToID = new TreeMap(); + private Map entryFlatToID = null; /** keys are the IDs given in STS file, values are indexes into flat arrays */ - private Map entryIDToFlat = new TreeMap(); + private Map entryIDToFlat = null; @@ -224,8 +224,19 @@ public StsReader(String FileName) ChareID = Integer.parseInt(st.nextToken()); st.nextToken(); // msgid - entryFlatToID.put(entryIndex, ID); - entryIDToFlat.put(ID,entryIndex); + // In general, Entry IDs will be contiguous starting from 0, so avoid + // creating the ID<->flat maps if possible. This code creates the map + // when it detects a non-contiguous case. + if (ID != entryIndex && entryFlatToID == null) { + entryFlatToID = new TreeMap<>(); + for (int i = 0; i < entryIndex; i++) + entryFlatToID.put(i, i); + entryIDToFlat = new TreeMap<>(entryFlatToID); + } + if (entryFlatToID != null) { + entryFlatToID.put(entryIndex, ID); + entryIDToFlat.put(ID, entryIndex); + } entryIndex++; getEntryNames().put(ID,Name); getEntryChare().put(ID, Chares[ChareID]); @@ -348,8 +359,13 @@ public String getEntryNameByID(int ID) { } public String getEntryNameByIndex(int index) { - if(entryFlatToID.containsKey(index)){ - return getEntryNames().get(entryFlatToID.get(index)); + // Check if the ID is valid. If entryFlatToID exists, then check if + // there's a valid mapping for index there, otherwise the index is the + // ID, so check in the entry names map directly. + final boolean isValid = (entryFlatToID != null && entryFlatToID.containsKey(index)) || + (entryFlatToID == null && getEntryNames().containsKey(index)); + if (isValid) { + return getEntryNames().get(getEntryID(index)); } else { return "Unknown"; } @@ -372,7 +388,7 @@ private String getEntryChareNameByID(int ID) { } public String getEntryChareNameByIndex(int index) { - return getEntryChare().get(entryFlatToID.get(index)).name; + return getEntryChare().get(getEntryID(index)).name; } public int getEntryChareDimensionsByID(int ID) { @@ -380,7 +396,7 @@ public int getEntryChareDimensionsByID(int ID) { } public int getEntryChareDimensionsByIndex(int index) { - return getEntryChare().get(entryFlatToID.get(index)).dimensions; + return getEntryChare().get(getEntryID(index)).dimensions; } public String getEntryFullNameByID(int ID) { @@ -391,12 +407,16 @@ public String getEntryFullNameByIndex(int index) { return getEntryChareNameByIndex(index) + "::" + getEntryNameByIndex(index); } - public Integer getEntryIndex(int ID) { - if(ID<0) - return ID; - return entryIDToFlat.get(ID); - } - + public int getEntryIndex(int ID) { + if(ID<0) + return ID; + return (entryIDToFlat == null) ? ID : entryIDToFlat.get(ID); + } + + private int getEntryID(int index) { + return (entryFlatToID == null) ? index : entryFlatToID.get(index); + } + // *** user event accessors *** public int getNumUserDefinedEvents() { return userEvents.size();