From 0ab933efffbb9b45bcca0432f08061cfcd7b8157 Mon Sep 17 00:00:00 2001 From: Skylot Date: Mon, 15 Nov 2021 21:02:29 +0000 Subject: [PATCH] perf: cache 'implements' list (heavily used in type inference) --- jadx-core/build.gradle | 2 + .../main/java/jadx/core/clsp/ClspGraph.java | 44 +++++++++---------- .../java/jadx/core/dex/nodes/RootNode.java | 1 + .../dex/visitors/OverrideMethodVisitor.java | 5 --- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/jadx-core/build.gradle b/jadx-core/build.gradle index 904c60b0b..4f7c48dc2 100644 --- a/jadx-core/build.gradle +++ b/jadx-core/build.gradle @@ -19,6 +19,8 @@ dependencies { testRuntimeOnly(project(':jadx-plugins:jadx-java-convert')) testRuntimeOnly(project(':jadx-plugins:jadx-java-input')) testRuntimeOnly(project(':jadx-plugins:jadx-raung-input')) + + testImplementation('tools.profiler:async-profiler:1.8.3') } test { diff --git a/jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java b/jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java index 3e07f1325..b36d0ffd2 100644 --- a/jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java +++ b/jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java @@ -28,8 +28,9 @@ public class ClspGraph { private static final Logger LOG = LoggerFactory.getLogger(ClspGraph.class); private final RootNode root; - private Map> superTypesCache; private Map nameMap; + private Map> superTypesCache; + private Map> implementsCache; private final Set missingClasses = new HashSet<>(); @@ -61,6 +62,11 @@ public class ClspGraph { } } + public void initCache() { + fillSuperTypesCache(); + fillImplementsCache(); + } + public boolean isClsKnown(String fullName) { return nameMap.containsKey(fullName); } @@ -114,13 +120,20 @@ public class ClspGraph { } public List getImplementations(String clsName) { - List list = new ArrayList<>(); - for (String cls : nameMap.keySet()) { - if (isImplements(cls, clsName)) { - list.add(cls); + List list = implementsCache.get(clsName); + return list == null ? Collections.emptyList() : list; + } + + private void fillImplementsCache() { + Map> map = new HashMap<>(nameMap.size()); + List classes = new ArrayList<>(nameMap.keySet()); + Collections.sort(classes); + for (String cls : classes) { + for (String st : getSuperTypes(cls)) { + map.computeIfAbsent(st, v -> new ArrayList<>()).add(cls); } } - return list; + implementsCache = map; } public String getCommonAncestor(String clsName, String implClsName) { @@ -157,24 +170,11 @@ public class ClspGraph { } public Set getSuperTypes(String clsName) { - if (superTypesCache != null) { - Set result = superTypesCache.get(clsName); - if (result == null) { - return Collections.emptySet(); - } - return result; - } - ClspClass cls = nameMap.get(clsName); - if (cls == null) { - missingClasses.add(clsName); - return Collections.emptySet(); - } - Set result = new HashSet<>(); - addSuperTypes(cls, result); - return result; + Set result = superTypesCache.get(clsName); + return result == null ? Collections.emptySet() : result; } - public synchronized void fillSuperTypesCache() { + private void fillSuperTypesCache() { Map> map = new HashMap<>(nameMap.size()); Set tmpSet = new HashSet<>(); for (Map.Entry entry : nameMap.entrySet()) { diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java index 59551af25..e462e9924 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java @@ -196,6 +196,7 @@ public class RootNode { ClspGraph newClsp = new ClspGraph(this); newClsp.load(); newClsp.addApp(classes); + newClsp.initCache(); this.clsp = newClsp; } } catch (Exception e) { diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/OverrideMethodVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/OverrideMethodVisitor.java index ecadf5742..becb7e225 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/OverrideMethodVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/OverrideMethodVisitor.java @@ -43,11 +43,6 @@ import jadx.core.utils.exceptions.JadxException; ) public class OverrideMethodVisitor extends AbstractVisitor { - @Override - public void init(RootNode root) throws JadxException { - root.getClsp().fillSuperTypesCache(); - } - @Override public boolean visit(ClassNode cls) throws JadxException { processCls(cls);