perf(res): XML decoding speed enhancement (PR #1293)
* chore: XML decoding speed improved for large APKs (finding class references) * skip attach class node to xml for SimpleCodeWriter (used in jadx-cli) Co-authored-by: Skylot <skylot@gmail.com>
This commit is contained in:
@@ -334,6 +334,15 @@ public class RootNode {
|
||||
return resolveClass(clsInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for ClassNode by its full name (original or alias name)
|
||||
*
|
||||
* Warning: This method has a runtime of O(n) (n = number of classes).
|
||||
* If you need to call it more than once consider {@link #buildFullAliasClassCache()} instead
|
||||
*
|
||||
* @param fullName
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
public ClassNode searchClassByFullAlias(String fullName) {
|
||||
for (ClassNode cls : classes) {
|
||||
@@ -346,6 +355,24 @@ public class RootNode {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, ClassNode> buildFullAliasClassCache() {
|
||||
Map<String, ClassNode> classNameCache = new HashMap<>(classes.size());
|
||||
for (ClassNode cls : classes) {
|
||||
ClassInfo classInfo = cls.getClassInfo();
|
||||
String fullName = classInfo.getFullName();
|
||||
String alias = classInfo.getAliasFullName();
|
||||
classNameCache.put(fullName, cls);
|
||||
if (alias != null && !fullName.equals(alias)) {
|
||||
classNameCache.put(alias, cls);
|
||||
}
|
||||
}
|
||||
return classNameCache;
|
||||
}
|
||||
|
||||
public List<ClassNode> searchClassByShortName(String shortName) {
|
||||
List<ClassNode> list = new ArrayList<>();
|
||||
for (ClassNode cls : classes) {
|
||||
|
||||
@@ -56,6 +56,8 @@ public class BinaryXMLParser extends CommonBinaryParser {
|
||||
private final RootNode rootNode;
|
||||
private String appPackageName;
|
||||
|
||||
private Map<String, ClassNode> classNameCache;
|
||||
|
||||
public BinaryXMLParser(RootNode rootNode) {
|
||||
this.rootNode = rootNode;
|
||||
try {
|
||||
@@ -78,7 +80,9 @@ public class BinaryXMLParser extends CommonBinaryParser {
|
||||
firstElement = true;
|
||||
decode();
|
||||
nsMap = null;
|
||||
return writer.finish();
|
||||
ICodeInfo codeInfo = writer.finish();
|
||||
this.classNameCache = null; // reset class name cache
|
||||
return codeInfo;
|
||||
}
|
||||
|
||||
private boolean isBinaryXml() throws IOException {
|
||||
@@ -467,6 +471,9 @@ public class BinaryXMLParser extends CommonBinaryParser {
|
||||
}
|
||||
|
||||
private void attachClassNode(ICodeWriter writer, String attrName, String clsName) {
|
||||
if (!writer.isMetadataSupported()) {
|
||||
return;
|
||||
}
|
||||
if (clsName == null || !attrName.equals("name")) {
|
||||
return;
|
||||
}
|
||||
@@ -476,7 +483,10 @@ public class BinaryXMLParser extends CommonBinaryParser {
|
||||
} else {
|
||||
clsFullName = clsName;
|
||||
}
|
||||
ClassNode classNode = rootNode.searchClassByFullAlias(clsFullName);
|
||||
if (classNameCache == null) {
|
||||
classNameCache = rootNode.buildFullAliasClassCache();
|
||||
}
|
||||
ClassNode classNode = classNameCache.get(clsFullName);
|
||||
if (classNode != null) {
|
||||
writer.attachAnnotation(classNode);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user