Skip to content

Commit b15f810

Browse files
author
Hristo Hristov
committed
Merge pull request #407 from NativeScript/hhristov/performance-optimization
Improve performance with 20-25%
2 parents edf6b65 + 3f4e2dc commit b15f810

4 files changed

Lines changed: 74 additions & 29 deletions

File tree

src/src/com/tns/ClassResolver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static Class<?> resolveClass(String fullClassName, DexFactory dexFactory,
3333

3434
if (clazz == null)
3535
{
36-
clazz = Class.forName(className);
36+
clazz = Platform.getClassForName(className);
3737
}
3838

3939
return clazz;

src/src/com/tns/DexFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ private File getDexFile(String className) throws InvalidClassException
216216
classToProxyFile += "-" + this.dexThumb;
217217
}
218218

219-
String dexFilePath = dexDir + classToProxyFile + ".dex";
219+
String dexFilePath = dexDir + "/" + classToProxyFile + ".dex";
220220
File dexFile = new File(dexFilePath);
221221
if (dexFile.exists())
222222
{

src/src/com/tns/MethodResolver.java

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -108,23 +108,27 @@ public static String getTypeSignature(Class<?> type)
108108
return array + signature;
109109
}
110110

111-
static String resolveMethodOverload(HashMap<String, Class<?>> classCache, String className, String methodName, Object[] args) throws ClassNotFoundException
111+
static HashMap<Class<?>, MethodFinder> methodOverloadsForClass = new HashMap<Class<?>, MethodFinder>();
112+
static ArrayList<Tuple<Method, Integer>> candidates = new ArrayList<Tuple<Method, Integer>>();
113+
114+
static String resolveMethodOverload(Class<?> clazz, String methodName, Object[] args) throws ClassNotFoundException
112115
{
113-
String methodSig = null;
114-
Class<?> clazz = classCache.get(className);
115-
if (clazz == null)
116-
{
117-
clazz = Class.forName(className);
118-
}
116+
candidates.clear();
119117
int argLength = (args != null) ? args.length : 0;
120118

121-
ArrayList<Tuple<Method, Integer>> candidates = new ArrayList<Tuple<Method, Integer>>();
122-
123119
Class<?> c = clazz;
124120
int iterationIndex = 0;
125121
while (c != null)
126122
{
127-
tryFindMatches(methodName, candidates, args, argLength, c.getDeclaredMethods());
123+
MethodFinder finder = methodOverloadsForClass.get(c);
124+
if (finder == null)
125+
{
126+
finder = new MethodFinder(c);
127+
methodOverloadsForClass.put(c, finder);
128+
}
129+
130+
ArrayList<Method> matchingMethods = finder.getMatchingMethods(methodName);
131+
tryFindMatches(methodName, candidates, args, argLength, matchingMethods);
128132
if (candidates.size() > iterationIndex && candidates.get(iterationIndex).y == 0)
129133
{
130134
// direct matching (distance 0) found
@@ -139,28 +143,18 @@ static String resolveMethodOverload(HashMap<String, Class<?>> classCache, String
139143
{
140144
if (candidates.size() > 1)
141145
Collections.sort(candidates, distanceComparator);
146+
142147
Method method = candidates.get(0).x;
143-
methodSig = getMethodSignature(method.getReturnType(), method.getParameterTypes());
148+
return getMethodSignature(method.getReturnType(), method.getParameterTypes());
144149
}
145150

146-
return methodSig;
151+
return null;
147152
}
148153

149-
static void tryFindMatches(String methodName, ArrayList<Tuple<Method, Integer>> candidates, Object[] args, int argLength, Method[] methods)
154+
static void tryFindMatches(String methodName, ArrayList<Tuple<Method, Integer>> candidates, Object[] args, int argLength, ArrayList<Method> methods)
150155
{
151156
for (Method method : methods)
152157
{
153-
if (!method.getName().equals(methodName))
154-
{
155-
continue;
156-
}
157-
158-
int modifiers = method.getModifiers();
159-
if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers))
160-
{
161-
continue;
162-
}
163-
164158
Class<?>[] params = method.getParameterTypes();
165159

166160
boolean success = false;
@@ -620,4 +614,38 @@ else if (primitiveType.equals(boolean.class))
620614

621615
return success;
622616
}
623-
}
617+
618+
static class MethodFinder {
619+
private Method[] declaredMethods;
620+
private HashMap<String, ArrayList<Method>> matchingMethods = new HashMap<String, ArrayList<Method>>();
621+
public MethodFinder(Class<?> clazz) {
622+
this.declaredMethods = clazz.getDeclaredMethods();
623+
}
624+
625+
public ArrayList<Method> getMatchingMethods(String methodName) {
626+
ArrayList<Method> matches = this.matchingMethods.get(methodName);
627+
if (matches == null) {
628+
matches = new ArrayList<Method>();
629+
for (Method method : this.declaredMethods)
630+
{
631+
if (!method.getName().equals(methodName))
632+
{
633+
continue;
634+
}
635+
636+
int modifiers = method.getModifiers();
637+
if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers))
638+
{
639+
continue;
640+
}
641+
642+
matches.add(method);
643+
}
644+
645+
matchingMethods.put(methodName, matches);
646+
}
647+
648+
return matches;
649+
}
650+
}
651+
}

src/src/com/tns/Platform.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ private static String[] getTypeMetadata(String className, int index) throws Clas
395395
if (clazz == null)
396396
{
397397
clazz = Class.forName(className);
398+
classCache.put(className, clazz);
398399
}
399400
}
400401

@@ -750,13 +751,29 @@ static Object[] packageArgs(Object... args)
750751

751752
return packagedArgs;
752753
}
754+
755+
static Class<?> getClassForName(String className) throws ClassNotFoundException {
756+
Class<?> clazz = classCache.get(className);
757+
if (clazz == null)
758+
{
759+
clazz = Class.forName(className);
760+
if (clazz != null) {
761+
classCache.put(className, clazz);
762+
}
763+
}
764+
765+
return clazz;
766+
}
753767

754768
@RuntimeCallable
755769
private static String resolveMethodOverload(String className, String methodName, Object[] args) throws Exception
756770
{
757771
if (logger.isEnabled())
758772
logger.write("resolveMethodOverload: Resolving method " + methodName + " on class " + className);
759-
String res = MethodResolver.resolveMethodOverload(classCache, className, methodName, args);
773+
774+
Class<?> clazz = getClassForName(className);
775+
776+
String res = MethodResolver.resolveMethodOverload(clazz, methodName, args);
760777
if (logger.isEnabled())
761778
logger.write("resolveMethodOverload: method found :" + res);
762779
if (res == null)
@@ -902,7 +919,7 @@ public static void purgeAllProxies()
902919
@RuntimeCallable
903920
private static Object createArrayHelper(String arrayClassName, int size) throws ClassNotFoundException
904921
{
905-
Class<?> clazz = Class.forName(arrayClassName);
922+
Class<?> clazz = getClassForName(arrayClassName);
906923

907924
Object arr = Array.newInstance(clazz, size);
908925

0 commit comments

Comments
 (0)