Java Reflection, 1000x Faster
norswap.com
norswap.com
The best approach without boilerplate would be to generate this at compile time, not runtime. You could use an approach like in http://hannesdorfmann.com/annotation-processing/annotationpr... to create at compile-time, using reflection, a ChildWalker class that accesses the relevant properties for every class annotated with @Node. At runtime, the JIT should get this down to a vtable lookup and field lookups - just about as optimized as you can get.
EDIT: Always remember https://xkcd.com/1205/ - if it would take 5 seconds to write each children() method, and you write no more than 5 Node classes per day (amortized), then you shouldn't spend more 12 hours writing the code for this blog post ;) Unless, of course, that was the point all along!
eg: JSX users.
If you use Kotlin instead of Java it's way better because no nullability-issues and it's super-useful standard-library.
And once you've figured out how to hook it into gradle, IDEA etc., which admittedly cost me an hour or so, you can reuse that knowledge for every annotation-processor to come.
I made it a habit to set myself a time-limit EVERY time I start touching the build-process. After the limit has passed it must be faster, more automated, or in any other way more useful, or I will revert the changes.
[0] https://medium.com/@spitzwegerich/generated-json-serialisati...
I'd love one that I could just point to a build tool/script instead of creating it's own.
Seems like I'm doing fine by xkcd, at least if you remove the time to make a simpler version for the blog post =) And the learning has some value too anyhow.
The fact that you have 100 classes implementing this is a good sign you should turn the design on its head. Why not just have a single tree structure built using generics?
edit: also I would point out that you're not really making reflection any faster, just your code
But that would (gasp!) require adding those implementations. Which is tedious (it is not with a bit of inheritance or some other technique but ok). OK, so, it requires a bit of work. But those methods would take a few (or a dozen) nanoseconds to dispatch; you can't go faster than that. What's the alternative? To build your brittle infrastructure? Hmmm, I must be missing something...
And if you make a breaking change to the interface, you better be damn well breaking it at compile time and not hiding it with reflection shenanigans.
In the example of the OP, it's easy to think of an example that would totally be broken by the author's reflection approach, while the user has no warning at compile time and no reasonable way of knowing that what he's doing isn't allowed:
class MyWeirdNode extends Node {
private final int i = 1;
public IntNode asIntNode() {
return new IntNode(i)
}
}Does anyone know why gui toolkits never do this? Every one seems to follow an OO model where each widget owns it's own children. Even in GTK they hacked in an OO system to do it instead of having a separate tree.
At the least, I'd have to populate the children list of that class (which is more or less what children() would have done). The identity of each child (what it represents), such as "condition of a while statement" or "body of the else part of an if statement" must be preserved.
Also, the issue with methods really isn't, because these classes are really POJOs. Getters and methods inherited from Object is pretty much all they have, so I'm not worried about accidentally capturing a method that is not a getter.
And well, this make reflection calls faster by replacing them (probably) with the equivalent plain code.
https://github.com/EsotericSoftware/reflectasm
When I needed something more custom, I've done the bytecode strategy a few times, using ASM library or equiv. But the cost of change (brittleness, aggravation) is pretty high.
Now I just write Java source and use the JDK's built-in javac to generate the bytecodes.
Some people like StringTemplate. http://www.stringtemplate.org For whatever reason, I still prefer Velocity. Template languages are mostly evil, and variations of terrible, so I just stick to what I know.
Annotations are never the correct answer. For any use case, purpose.
Edit: Whoops. May have spoke too soon. JDK 8's MethodHandle and some other features (inlining simple getters) may have mooted ReflectASM. https://github.com/EsotericSoftware/reflectasm/issues/23 I may have to retool some of my older code.
I'm just a simple bear. I can't keep all the details straight.
One strategy I use to cope is round tripping, as a way to confirm I get the expected results.
My current approach to code generation: painstakingly hand craft the desired source code output. Then turn that into a template (progressive refinement). Then compare (diff) generated output to manual. Iterate. Many times that means adjusting target to make it easier to generate.
Using bytecodes (class file) as the target output adds complexity and more steps. I've been reversing bytecodes for a long time, manually using javap, the decompilers (which are now quite good), and using ASMs code generator plugin for Eclipse (super clever). But it's too fussy, compared to the Java source code strategy.
That's a pretty absurd claim, especially given their popularity.
What do you use to annotate elements present in a Java source with metadata?
Regardless, MethodHandle invocations are always going to be faster than reflection Method invocations. A primary reason is that the parameters for invoke and invokeExact are not subject to the same boxing and runtime-validation requirements as reflection.
No you didn't. An interface representing a tree node would have a children() method.
I don't know about Java but in .NET there's a call you can make to force the dynamically generated lamba expression to be compiled immediately.
Of course if you're being really adventurous you can use IL emit to build a function up from IL opcodes.
http://openjdk.java.net/projects/code-tools/jmh/
It takes care of details like JVM warm-ups. ensuring sufficient invocations for JIT compilation to have occurred, etc.
Testing with CompilerControl.Mode.EXCLUDE in JMH is still more reliable than testing manually, when you don't know if it got compiled or not.
Interpreted code is a case where method handles should be much faster than the generated accessor classes used by reflection - lambdas and method references are faster than an inner class implementing a functional interface before jit compilation. Afterwards, performance tends to be sameish.
I came across some code a few weeks ago that skipped this step. It wasn't called remotely often enough to justify the complication in the first place (low volume internal web app) but it didn't cache the result so it ended up making things slower. Thanks to the wonders of RenderAction in MVC it compiled the dynamic IL 20 times per page view as well.
[1] https://docs.oracle.com/javase/7/docs/api/java/beans/Introsp...
When the unit test fails for a node type it prints what it should be and you just copy and paste that code for children() should be.
This is also nice for the case where nodes have some sort special children(). You can make the unit test ignore those.
Here are the limitations of the Mono runtime:
https://developer.xamarin.com/guides/ios/advanced_topics/lim...
However, there are ways of compiling the little snippets of the code you need ahead of time, then plugging them together with delegates at runtime, which avoids much of the overhead.
Much of the cost is the overhead of converting from unknown types to specific types. So you can pre-compile loosely typed adaptor thunks that take generic "object" arguments, convert them to the required type, and directly call strongly typed delegates (which you can plug into the adaptor, so adaptors can be used for any number of compatible delegates).
Check out how the following code uses FastInvoke, ToOpenDelegate, Delegate.CreateDelegate, Expression.GetActionType, and Expression.GetFuncType.
It may be that some of these general techniques could be applied to Java.
Faster Invoke for reflected property access and method invocation with AOT compilation:
https://web-beta.archive.org/web/20120826100615/http://whydo...
The bane of the iOS programmers life, when working with reflection in Mono, is that you cant go around making up new generic types to ensure that your reflected properties and methods get called at decent speed. This is because Mono on iOS is fully Ahead Of Time compiled and simply cant make up new stuff as you go along. That coupled with the dire performance of Invoke when using reflected properties lead me to construct a helper class.
This works by registering a series of method signatures with the compiler, so that they are available to code running on the device. In my tests property access was 4.5x faster and method access with one parameters was 2.4x faster. Not earth shattering but every little helps. If you knew what you wanted ahead of time, then you could probably do a lot better. See here for info.
You have to register signatures inside each class Im afraid. Nothing I can do about that.
So to register a signature you use:
static MyClass()
{
//All methods returning string can be accelerated
DelegateSupport.RegisterFunctionType<MyClass, string>();
//All methods returning string and taking an int can be accelerated
DelegateSupport.RegisterFunctionType<MyClass, int, string>();
//All methods returning void and taking a bool can be accelerated
DelegateSupport.RegisterActionType<MyClass, bool>();
}
Then when you have a MethodInfo you use the extension method
FastInvoke(object target, params object[] parameters) to call
it. FastInvoke will default to using normal Invoke if you havent
accelerated a particular type.myObject.GetType().GetProperty("SomeProperty").GetGetMethod().FastInvoke(myObject);
myObject.GetType().GetMethod("SomeMethod").FastInvoke(myObject, 1, 2);
You can download the source code for FastInvoke from here.
https://web-beta.archive.org/web/20120826100615/http://www.w...
Newer version from unityserializer-ng:
https://gitgud.io/TheSniperFan/unityserializer-ng/blob/maste...