Performance of reflection: quality byte code in JVM - java

Edit 2:
Does a program with a fully object-oriented implementation give high performance? Most of the framework is written with full power of it. However, reflection is also heavily used to achieve it like for AOP and dependency injection. Use of reflection affects the performance to a certain extent.
So, Is it good practice to use reflection? Is there some alternative to reflection from programming language constructs? To what extent should reflection be used?

Reflection is, in itself and by nature, slow. See this question for more details.
This is caused by a few reasons. Jon Skeet explains it nicely:
Check that there's a parameterless constructor Check the accessibility
of the parameterless constructor Check that the caller has access to
use reflection at all Work out (at execution time) how much space
needs to be allocated Call into the constructor code (because it won't
know beforehand that the constructor is empty)
Basically, reflection has to perform all the above steps before invocation, whereas normal method invocation has to do much less.
The JITted code for instantiating B is incredibly lightweight.
Basically it needs to allocate enough memory (which is just
incrementing a pointer unless a GC is required) and that's about it -
there's no constructor code to call really; I don't know whether the
JIT skips it or not but either way there's not a lot to do.
With that said, there are many cases where Java is not dynamic enough to do what you want, and reflection provides a simple and clean alternative. Consider the following scenario:
You have a large number of classes which represent various items, i.e. a Car, Boat, and House.
They both extend/implement the same class: LifeItem.
Your user inputs one of 3 strings, "Car", "Boat", or "House".
Your goal is to access a method of LifeItem based on the parameter.
The first approach that comes to mind is to build an if/else structure, and construct the wanted LifeItem. However, this is not very scalable and can become very messy once you have dozens of LifeItem implementations.
Reflection can help here: it can be used to dynamically construct a LifeItem object based on name, so a "Car" input would get dispatched to a Car constructor. Suddenly, what could have been hundreds of lines of if/else code turns into a simple line of reflection. The latter scenario would not be as valid on a Java 7+ platform due to the introduction of switch statements with Strings, but even then then a switch with hundreds of cases is something I'd want to avoid. Here's what the difference between cleanliness would look like in most cases:
Without reflection:
public static void main(String[] args) {
String input = args[0];
if(input.equals("Car"))
doSomething(new Car(args[1]));
else if(input.equals("Boat"))
doSomething(new Boat(args[1]));
else if (input.equals("House"))
doSomething(new House(args[1]));
... // Possibly dozens more if/else statements
}
Whereas by utilizing reflection, it could turn into:
public static void main(String[] args) {
String input = args[0];
try {
doSomething((LifeItem)Class.forName(input).getConstructor(String.class).newInstance(args[1]));
} catch (Exception ie) {
System.err.println("Invalid input: " + input);
}
}
Personally, I'd say the latter is neater, more concise, and more maintainable than the first. In the end its a personal preference, but that's just one of the many cases where reflection is useful.
Additionally, when using reflection, you should attempt to cache as much information as possible. In other words employ simple, logical things, like not calling get(Declared)Method everywhere if you can help it: rather, store it in a variable so you don't have the overhead of refetching the reference whenever you want to use it.
So those are the two extremes of the pro's and con's of reflection. To sum it up if reflection improves your code's readability (like it would in the presented scenario), by all means go for it. And if you do, just think about reducing the number of get* reflection calls: those are the easiest to trim.

While reflection is most expensive than "traditional code", premature optimization is the root of all evil. From a decade-long empirical evidence, I assume that a method invoked via reflection will hardly affect performance unless it is invoked from a heavy loop, and even so there have been some performance enhancements on reflection:
Certain reflective operations, specifically Field, Method.invoke(),
Constructor.newInstance(), and Class.newInstance(), have been
rewritten for higher performance. Reflective invocations and
instantiations are several times faster than in previous releases
Enhancements in J2SDK 1.4 -
Note that method lookup (i.e. Class.getMethod) is not mentioned above, and choosing the right Method object usually requires additional steps such as traversing the class hierarchy while asking for the "declared method" in case that it is not public), so I tend to save the found Method in a suitable map whenever it is possible, so that the next time the cost would be only that of a Map.get() and Method.invoke(). I guess that any well-written framework can handle this correctly.
One should also consider that certain optimizations are not possible if reflection is used (such as method inlining or escape analysis. Java HotSpotâ„¢ Virtual Machine Performance Enhancements). But this doesn't mean that reflection has to be avoided at all cost.
However, I think that the decision of using reflection should be based in other criteria, such as code readability, maintainability, design practices, etc. When using reflection in your own code (as opposed to using a framework that internally uses reflection), one risk transforming compile-time errors into run-time errors, which are harder to debug. In some cases, one could replace the reflective invocation by a traditional OOP pattern such as Command or Abstract Factory.

I can give you one example (but sorry, I can't show you the test results, because it was few months ago). I wrote an XML library (custom project oriented) which replaced some old DOM parser code with classes + annotations. My code was half the size of the original. I did tests, and yes, reflection was more expensive, but not much (something like 0.3 seconds out of 14-15 seconds of executing (loss is about 2%)). In places, where code is executed infrequently, reflection can be used with a small performance loss.
Moreover, I am sure, that my code can be improved for better performance.
So, I suggest these tips:
Use reflection if you can do it in a way that is beautiful, compact & laconic;
Do not use reflection if your code will be executed many-many times;
Use reflection, if you need to project a huge amount of information from another source (XML-files, for example) to Java application;
The best usage for reflections and annotations is where code is executed only once (pre-loaders).

Related

Do private functions use more or less computer resources than public ones?

Computer resources being RAM, possessing power, and disk space. I am just curious, even though it is more or less by a tiny itty-bitty amount.
It could, in theory, be a hair faster in some cases. In practice, they're equally fast.
Non-static, non-public methods are invoked using the invokevirtual bytecode op. This opcode requires the JVM to dynamically look up the actual's method resolution: if you have a call that's statically compiled to AbstractList::contains, should that resolve to ArrayList::contains, or LinkedList::contains, etc? What's more, the compiler can't just reuse the result of this compilation for next time; what if the next time that myList.contains(val) gets called, it's on a different implementation? So, the compiler has to do at least some amount of checking, roughly per-invocation, for non-private methods.
Private methods can't be overridden, and they're invoked using invokespecial. This opcode is used for various kind of method calls that you can resolve just once, and then never change: constructors, call to super methods, etc. For instance, if I'm in ArrayList::add and I call super.add(value) (which doesn't happen there, but let's pretend it did), then the compiler can know for sure that this refers to AbstractList::add, since a class's super class can't ever change.
So, in very rough terms, an invokevirtual call requires resolving the method and then invoking it, while an invokespecial call doesn't require resolving the method (after the first time it's called -- you have to resolve everything at least once!).
This is covered in the JVM spec, section 5.4.3:
Resolution of the symbolic reference of one occurrence of an invokedynamic instruction does not imply that the same symbolic reference is considered resolved for any other invokedynamic instruction.
For all other instructions above, resolution of the symbolic reference of one occurrence of an instruction does imply that the same symbolic reference is considered resolved for any other non-invokedynamic instruction.
(empahsis in original)
Okay, now for the "but you won't notice the difference" part. The JVM is heavily optimized for virtual calls. It can do things like detecting that a certain site always sees an ArrayList specifically, and so "staticify" the List::add call to actually be ArrayList::add. To do this, it needs to verify that the incoming object really is the expected ArrayList, but that's very cheap; and if some earlier method call has already done that work in this method, it doesn't need to happen again. This is called a monomorphic call site: even though the code is technically polymorphic, in practice the list only has one form.
The JVM optimizes monomorphic call sites, and even bimorphic call sites (for instance, the list is always an ArrayList or a LinkedList, never anything else). Once it sees three forms, it has to use a full polymorphic dispatch, which is slower. But then again, at that point you're comparing apples to oranges: a non-private, polymorphic call to a private call that's monomorphic by definition. It's more fair to compare the two kinds of monomorphic calls (virtual and private), and in that case you'll probably find that the difference is minuscule, if it's even detectible.
I just did a quick JMH benchmark to compare (a) accessing a field directly, (b) accessing it via a public getter and (c) accessing it via a private getter. All three took the same amount of time. Of course, uber-micro benchmarks are very hard to get right, because the JIT can do such wonderful things with optimizations. Then again, that's kind of the point: The JIT does such wonderful things with optimizations that public and private methods are just as fast.
Do private functions use more or less computer resources than public ones?
No. The JVM uses the same resources regardless of the access modifier on individual fields or methods.
But, there is a far better reason to prefer private (or protected) beside resource utilization; namely encapsulation. Also, I highly recommend you read The Developer Insight Series: Part 1 - Write Dumb Code.
I am just curious, even though it is more or less by a tiny itty-bitty amount.
While it is good to be curious ... if you start taking this kind of thing into account when you are programming, then:
you are liable to waste a lot of time looking for micro-optimizations that are not needed,
your code is liable to be unmaintainable because you are sacrificing good design principles, and
you even risk making your code less efficient* than it would be if you didn't optimize.
* - It it can go like this. 1) You spend a lot of time tweaking your code to run fast on your test platform. 2) When you run on the production platform, you find that the hardware gives you different performance characteristics. 3) You upgrade the Java installation, and the new JVM's JIT compiler optimizes your code differently, or it has a bunch of new optimizations that are inhibited by your tweaks. 4) When you run your code on real-world workloads, you discover that the assumption that were the basis for your tweaking are invalid.

Having pairs of static and instanced methods that perform the same tasks?

While developing a two-dimensional vector class as part of a math library, I'm considering having static and instance method pairs for stylistic and usability reasons. That is, two equivalent functions but one is static & non-mutating, and the other is instanced & mutating. I know I'm not the first person to consider this problem (See here, for example) but I haven't found any information that directly addresses it.
Pros of having static and instance method pairs:
Some people prefer to use one or the other and in some cases being able to choose makes code easier to read.
It is implied that static methods are not mutating when both static and instanced methods are provided. This can make the calling code much clearer, e.g.:
someVector = Vector2d.add(vec1, vec2);
someVector = (new Vector2d(vec1)).add(vec2); // does the same thing although more convoluted.
// similarly adding directly to a vector is simpler with a mutator method.
someVector.add(vec2);
someVector = Vector2d.add(someVector, vec2);
This is especially important when long chains of function calls are used, which is common with vectors.
In-place operations can be faster computationally than creating a new instance for every operation. The user decides when performance is important. For users of a Vector class, performance may be important as vectors are frequently used in computationally expensive code.
Pros of having only static or instance methods, but not both:
No significant code redundancy. Easier to maintain.
Less bloat. The javadocs will be almost half the size.
Not necessary to inform users that static methods never mutate and non-getter instanced methods always mutate.
How frowned upon is having static/instance method pairs? Is it used in any major libraries?
Is the pattern "static methods don't mutate, instance methods do" widely known?
I think your concept of providing both static/immutable and instance/mutable methods is a good one. I think the distinction is easy to explain and will be easy for the API users to understand and remember.
I think your API implementation code will not have redundant business logic. You will find that that you repeat a pattern where the static implementation creates a new instance and calls the instance method on that new instance.
Given that I am lazy, I would look at building a bit of infrastructure that would auto-generate the static methods, their javadoc and their unit tests at compile-time. This would be overkill if you have 10 methods, but becomes a big win if you have 1,000 methods.
On the first part, "static methods don't mutate", that's widely used in OOP. I haven't heard of it being expressed explicitly. But it is common sense: "If you change an object, why would the method be static if it could be an instance method?" So I completely agree with the "static methods don't mutate".
On the second part, "instance methods do [mutate]", that's actually not as widely used. It rather depends on whether you decide your design to apply immutability or mutability. Examples from the Java API: java.lang.String is immutable, java.util.Date is mutable (most likely by accident / bad design), java.lang.StringBuilder is mutable intentionally (that's its purpose). Mutability can lead to defensive cloning in order to protect the code from mutation bugs. Whether this really is a problem depends on a few things:
Is it an API others will use? You never know how they will use your code... IMO it's more important to protect API code from mutation bugs than normal code.
How good is the unit test coverage? Would your unit tests find all the mutation bugs that might sneak in? If you follow TDD properly (Uncle Bob's 3 Laws of TDD), and it's non-API code, mutation bugs are very unlikely to sneak in without being instantly discovered.
If you have code that has to protect itself against mutation bugs using defensive cloning, how often is that code called? If defensive clones are created frequently, it might be better to use immutable objects than mutable objects. Basically this is the call of the number of calls of read-only methods (that would eventually defensively clone) of associating classes vs. the number of calls of mutator methods on the class itself.
Personally, I prefer immutable objects, I'm a fan of final (if I could change Java, I would make final the default for all fields and variables, and introduce a keyword var to make them non-final), and I try to do functional programming in Java, although it is not a functional programming language, as much as possible. From my experience I know that I spend significantly less time debugging my code than others (actually I run the Java debugger maybe twice a year or so). I do not have enough empirical data and proper analysis for creating any kind of "causal relationship" between experience, immutability, functional programming and correctness, therefore I will only say I believe that immutability and functional programming help for correctness, and you will have to come up with your own judgement on this.
Concluding on the second part, "instance methods do [mutate]" is the widely used assumption in case the object is mutable anyway, otherwise instance methods would clone.

Is Object.class.getName() Slow?

I'm writing code in the Java ME environment, so speed is absolutely an important factor. I have read several places that reflection of any sort (even the very limited amounts that are allowed on java ME) can be a very large bottleneck.
So, my question is this: is doing String.class.getName() slow? What about myCustomObject.getClass().getName()? Is it better to simply replace those with string constants, like "java.lang.String" and "com.company.MyObject"?
In case you're wondering, I need the class names of all primitives (and non-primitives as well) because Java ME does not provide a default serialization implementation and thus I have to implement my own. I need a generic serialization solution that will work for both communication across the network as well as local storage (RMS, but also JSR-75)
Edit
I'm using Java 1.3 CLDC.
String.class.getName() would be not slow because its value will be loaded before executed.i.e compiler will put its value before line will execute.
myCustomObject.getClass().getName() would be bit slower then previous as it will be retrieved at time for execution
Reflection is not unnaturally slow; it's just as slow as you'd expect, but no slower. First, calling a method via reflection requires all the object creation and method calling that is obvious from the reflection API, and second, that if you're calling methods through reflection, Hotspot won't be able to optimize through the calls.
Calling getClass().getName() is no slower than you'd expect, either: the cost of a couple of virtual method calls plus a member-variable fetch. The .class version is essentially the same, plus or minus a variable fetch.
I can't speak for Java ME, but I'm not surprised at the overhead by using reflection on a resource constrained system. I wouldn't think it is unbearably slow, but certainly you would see improvements from hard-coding the names into a variable.
Since you mentioned you were looking at serialization, I'd suggest you take a look into how its done in the Kryo project. You might find some of their methods useful, heck you might even be able to use it in Java ME. (Unfortunately, I have no experience with ME)

Java super-tuning, a few questions

Before I ask my question can I please ask not to get a lecture about optimising for no reason.
Consider the following questions purely academic.
I've been thinking about the efficiency of accesses between root (ie often used and often accessing each other) classes in Java, but this applies to most OO languages/compilers. The fastest way (I'm guessing) that you could access something in Java would be a static final reference. Theoretically, since that reference is available during loading, a good JIT compiler would remove the need to do any reference lookup to access the variable and point any accesses to that variable straight to a constant address. Perhaps for security reasons it doesn't work that way anyway, but bear with me...
Say I've decided that there are some order of operations problems or some arguments to pass at startup that means I can't have a static final reference, even if I were to go to the trouble of having each class construct the other as is recommended to get Java classes to have static final references to each other. Another reason I might not want to do this would be... oh, say, just for example, that I was providing platform specific implementations of some of these classes. ;-)
Now I'm left with two obvious choices. I can have my classes know about each other with a static reference (on some system hub class), which is set after constructing all classes (during which I mandate that they cannot access each other yet, thus doing away with order of operations problems at least during construction). On the other hand, the classes could have instance final references to each other, were I now to decide that sorting out the order of operations was important or could be made the responsibility of the person passing the args - or more to the point, providing platform specific implementations of these classes we want to have referencing each other.
A static variable means you don't have to look up the location of the variable wrt to the class it belongs to, saving you one operation. A final variable means you don't have to look up the value at all but it does have to belong to your class, so you save 'one operation'. OK I know I'm really handwaving now!
Then something else occurred to me: I could have static final stub classes, kind of like a wacky interface where each call was relegated to an 'impl' which can just extend the stub. The performance hit then would be the double function call required to run the functions and possibly I guess you can't declare your methods final anymore. I hypothesised that perhaps those could be inlined if they were appropriately declared, then gave up as I realised I would then have to think about whether or not the references to the 'impl's could be made static, or final, or...
So which of the three would turn out fastest? :-)
Any other thoughts on lowering frequent-access overheads or even other ways of hinting performance to the JIT compiler?
UPDATE: After running several hours of test of various things and reading http://www.ibm.com/developerworks/java/library/j-jtp02225.html I've found that most things you would normally look at when tuning e.g. C++ go out the window completely with the JIT compiler. I've seen it run 30 seconds of calculations once, twice, and on the third (and subsequent) runs decide "Hey, you aren't reading the result of that calculation, so I'm not running it!".
FWIW you can test data structures and I was able to develop an arraylist implementation that was more performant for my needs using a microbenchmark. The access patterns must have been random enough to keep the compiler guessing, but it still worked out how to better implement a generic-ified growing array with my simpler and more tuned code.
As far as the test here was concerned, I simply could not get a benchmark result! My simple test of calling a function and reading a variable from a final vs non-final object reference revealed more about the JIT than the JVM's access patterns. Unbelievably, calling the same function on the same object at different places in the method changes the time taken by a factor of FOUR!
As the guy in the IBM article says, the only way to test an optimisation is in-situ.
Thanks to everyone who pointed me along the way.
Its worth noting that static fields are stored in a special per-class object which contains the static fields for that class. Using static fields instead of object fields are unlikely to be any faster.
See the update, I answered my own question by doing some benchmarking, and found that there are far greater gains in unexpected areas and that performance for simple operations like referencing members is comparable on most modern systems where performance is limited more by memory bandwidth than CPU cycles.
Assuming you found a way to reliably profile your application, keep in mind that it will all go out the window should you switch to another jdk impl (IBM to Sun to OpenJDK etc), or even upgrade version on your existing JVM.
The reason you are having trouble, and would likely have different results with different JVM impls lies in the Java spec - is explicitly states that it does not define optimizations and leaves it to each implementation to optimize (or not) in any way so long as execution behavior is unchanged by the optimization.

Hibernate implementation. Are we paying the reflection penalty?

Long time ago, I was creating a mini ORM using reflection.
While reading about reflection I got a similar answer like this:
Java Reflection Performance
Which makes completely sense and I quit my mini orm and sharpen my CTRL+C, CTRL+V keys ( the lib was intended to avoid having to rewrite again and again the same snippets for different tables in a web app I was working on )
Years later for some reason I don't remember now ( nor want to remeber ) I was reading ( or trying to... ) the Hibernate source code, for I wanted to know if they use AOP to generate code on the fly and avoid the reflection penalty, but for my surprise, all of what I saw was pure reflection.
Does it mean the most accepted ORM framework out there, did exactly what years before discourage me from continuing my naive efforts ?? :")
My question is: Can someone confirm my understanding of the Hibernate implementation? Do they generate bytecode on the fly to improve performance? Or are we ( when we use it ) always paying the reflection penalty ( which by the way, if the diff is in some ms, none of us have noticed nor complained about )
Are we paying the reflection penalty? If we are, I think it is worth it!!!
Regards.
Hibernate instruments your models to be hibernate aware.
There are varying levels of cost for using Reflection. Constantly looking up a method for a particular class is particularly expensive. Executing a method via reflection using a cached copy is not that much slower. If one thinks of the tasks that the reflection api must complete to invoke the method it all makes sense which each part is slow and consumes cpu cycles.
Locating a method
Visit each and every method of a particular class
Test each methods visibility, method signature etc.
Generate bytecode for found method.
One factors in the numbers of methods in a typical class and that some of these operations arent trivial it becomes obvious that this can be costly.
Invoking the method.
Each reflected method amounts to a bit of byte code that invokes the target method with a bit of boilerplate to match the reflection interface. Before it can do that it must perform some sanity checks so it can complain with nice messages rather than letting the runtime throw ClassCastException and similar exceptions.
If an instance method check the instance passed in isnt null and is the right type.
Check the arguments parameter includes the right amount and type of parameters.
Execute the method within a try catch. In the catch throw ITE etc.
All these extras add some cost - not a lot but it does make things slower.
Runtime costs
In general caching methods and invoking that isnt cost but is a bit slower. The reflection api itself does attempt to cache methods and classes but finding the right method and so on is still a slow operation.
I think the important thing to remember is the relative cost in the overall application. Is reflection slower then normal object creation? Yes. Has reflection got better and faster? Yes. But really these points aren't very important when comparing the cost of reflection versus going over the wire and doing something with the database, which is what hibernate does - the cost becomes completely negligible and I'd say we are not paying the price.
The cost of persistence and retrieval is many times the cost of reflection. To access a record from a DB might take 1-10 ms and to construct an object with reflection might take 0.001 to 0.01 ms.
Doesn't NHibernate cache the class info gathered through reflection so you only pay the penalty the first time?
You really pay the reflection penalty by using NHibernate but its extensibility allow you to avoid 90% of them if you provide all optimized reflection implementation via NHibernate.Bytecode.IBytecodeProvider.

Categories