Created
June 2, 2018 02:06
-
-
Save cramja/6ced82915736da7374ca8ba1ca2d9869 to your computer and use it in GitHub Desktop.
Understand the performance impact of reflection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.common.collect.ImmutableMap; | |
import com.google.common.math.Stats; | |
import java.lang.reflect.InvocationTargetException; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Map; | |
public class ReflectionTest { | |
public interface FooGetter { | |
String getFoo(); | |
} | |
public static class Foo implements FooGetter{ | |
public String getFoo() { | |
return "foo"; | |
} | |
} | |
public static void main(String[] args) | |
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { | |
final int numTrials = 100; | |
final int warmupBuffer = 10; | |
FooGetter getFoo = new Foo(); | |
Map<Class, FooGetter> getterMap = ImmutableMap.of(Foo.class, getFoo); | |
List<Long> getTimesNoReflection = new ArrayList<>(numTrials); | |
for (int i = 0; i < numTrials + warmupBuffer; i++) { | |
long startTime = System.nanoTime(); | |
getterMap.get(Foo.class).getFoo(); | |
getTimesNoReflection.add(System.nanoTime() - startTime); | |
} | |
List<Long> getTimesReflection = new ArrayList<>(numTrials); | |
for (int i = 0; i < numTrials + warmupBuffer; i++) { | |
long startTime = System.nanoTime(); | |
Foo.class.getMethod("getFoo").invoke(getFoo); | |
getTimesReflection.add(System.nanoTime() - startTime); | |
} | |
getTimesNoReflection = getTimesNoReflection.subList(warmupBuffer, getTimesNoReflection.size()); | |
getTimesReflection = getTimesReflection.subList(warmupBuffer, getTimesReflection.size()); | |
double logMeanParseTime = Math.log10(Stats.of(getTimesNoReflection).mean()); | |
double logMeanConvertTime = Math.log10(Stats.of(getTimesReflection).mean()); | |
System.out.printf("without reflection: %s | %f%n", Stats.of(getTimesNoReflection).toString(), logMeanParseTime); | |
System.out.printf("with reflection: %s | %f%n", Stats.of(getTimesReflection).toString(), logMeanConvertTime); | |
// output: | |
// without reflection: Stats{count=100, mean=613.9799999999997, populationStandardDeviation=665.633637671655, min=386.0, max=4904.0} | 2.788154 | |
// with reflection: Stats{count=100, mean=29551.36000000001, populationStandardDeviation=240902.67234032584, min=3358.0, max=2425919.0} | 4.470577 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I added a third metric, which buffers the
Method
so thatgetMethod
gets invoked only once. Got interesting results.Full source: