Reflection runtime performance - Java vs CLR - java

A related post here pretty much established reflection in Java as a performance hog. Does that apply to the CLR as well? (C#, VB.NET, etc).
EDIT: How does the CLR compare to Java when it comes to reflection? Was that ever benchmarked?

I wouldn't really care about the instantiation performance of the object using reflection itself but the actual performance of methods and such since those are after all what I'll be using from the class anyway.
Surely the instantiation takes a lot of time as can be seen in the linked post but since you're most likely using the object's methods instead of just instantiating it, you shouldn't worry too much about reflection performance - as long as you're not doing the method calls by invoking reflected Method objects!
Besides you only need one reflected instance of the object, use .clone() and other clever tricks if you need to create more copies.

Yeah, reflection in .NET is a performance intensive operation too as it requires querying metadata tables in assemblies.

The default implementation of Equals for value types is implemented using Reflection. It works, but it is darn slow and it is easy to implement a specific version, which is much faster (the catch is that you have to implement GetHashCode as well). How much faster depends on the actual value type of course, but I have seen some huge boosts here.

Related

When creating multiple instances of the same object, does Java replicate the method implementations?

I've tried searching around for my answer but can't seem to find one.
I was curious if Java and or other modern languages optimize the replication of objects by doing some sort of virtual mapping for the methods. It would seem to be a waste if every time a new instance of a object is created, it would copy the methods associated with it rather then perhaps mapping these to one place in memory.
I can see some cases, such as polymorphism, where it might not work.
This might be more of a fundamentals question but I am very curious how the compiler handles this.
Thanks!
Strictly speaking, it's none of your business:
The Java Virtual Machine does not mandate any particular internal structure for objects.
(JVM Spec)
So, if you were to write your own JVM, and for some reason you chose to put a copy of method code into every in-memory representation of an object, you would be free to do so.
However, there are various aspects of how the language is defined, that mean that it's not possible for two objects of the same class to have methods that differ -- even if they're non-static inner classes, dynamic classes, etc.
Therefore you're right that it would be wasteful of space to duplicate the method code for each instance, and no serious implementation of Java does so.

Is it good practice in Java to implement the clone method using serialization?

I saw several tutorials online where serialization and subsequent deserialization is used to implement deep cloning in Java.
My feeling is, that this is a solution that is fast to implement and therefore widespread but might have caveats that I currently don't see.
Is that way of implementing clone() good style? Isn't it slow? Should deep cloning really be done that way? What better ways exist?
Is it good practice in Java to implement the clone method using
serialization?
If you use serialization to clone an object you have to necessarily unserialize the serialized object to create the cloned object. It makes two operations where the second seems be an overhead as it should not be performed if you implement the cloning operation at the hand or with a mapper API (ex: SpringBean, Common apache, ModelMapper, Dozzer...).
So it has without no doubt an impact on the performance. If you do this processing very occasionally, I don't think that it should be a problem (even if it seems to be a useless overhead and you have alternative ways) but if you use it often I think that it may have a cost.
Besides, why implementing Clonable to clone an object by using serialization instead of forgetting Cloneable that is a clumsy API and using directly the deserialization mechanism ?

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)

MethodHandle - What is it all about?

I am studying new features of JDK 1.7 and I just can't get it what MethodHandle is designed for? I understand (direct) invocation of the static method (and use of Core Reflection API that is straightforward in this case). I understand also (direct) invocation of the virtual method (non-static, non-final) (and use of Core Reflection API that requires going through Class's hierarchy obj.getClass().getSuperclass()). Invocation of non-virtual method can be treated as special case of the former one.
Yes, I aware that there is an issue with overloading. If you want to invoke method you have to supply the exact signature. You can't check for overloaded method in easy way.
But, what is MethodHandle about? Reflection API allows you to "look on" the object internals without any pre-assumption (like implemented the interface). You can inspect the object for some purpose. But what is MethodHandle is designed too? Why and when should I use it?
UPDATE: I am reading now this http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html article. According to it, the main goal is to simplify life for scripting languages that runs atop of JVM, and not for Java Language itself.
UPDATE-2: I finish to read the link above, some quotation from there:
The JVM is going to be the best VM for building dynamic languages, because it already is a dynamic language VM. And InvokeDynamic, by promoting dynamic languages to first-class JVM citizens, will prove it.
Using reflection to invoke methods works great...except for a few problems. Method objects must be retrieved from a specific type, and can't be created in a general way.<...>
...reflected invocation is a lot slower than direct invocation. Over the years, the JVM has gotten really good at making reflected invocation fast. Modern JVMs actually generate a bunch of code behind the scenes to avoid a much of the overhead old JVMs dealt with. But the simple truth is that reflected access through any number of layers will always be slower than a direct call, partially because the completely generified "invoke" method must check and re-check receiver type, argument types, visibility, and other details, but also because arguments must all be objects (so primitives get object-boxed) and must be provided as an array to cover all possible arities (so arguments get array-boxed).
The performance difference may not matter for a library doing a few reflected calls, especially if those calls are mostly to dynamically set up a static structure in memory against which it can make normal calls. But in a dynamic language, where every call must use these mechanisms, it's a severe performance hit.
http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html
So, for Java programmer it is essentially useless. Am I right? From this point of view, It can be only considered as alternative way for Core Reflection API.
UPDATE-2020: Indeed, MethodHandle can be thought as s more powerful alternative to Core Reflection API. Starting with JDK 8 there are also Java Language features that use it.
What you can do with MethodHandles is curry methods, change the types of parameters and change their order.
Method Handles can handle both methods and fields.
Another trick which MethodHandles do is use primitive direct (rather than via wrappers)
MethodHandles can be faster than using reflection as there is more direct support in the JVM e.g they can be inlined. It uses the new invokedynamic instruction.
Think of MethodHandle as a modern, more flexible, more typesafe way of doing reflection.
It's currently in the early stages of its lifecycle - but over time has the potential to be optimized to become must faster than reflection - to the point that it can become as fast as a regular method call.
java.lang.reflect.Method is relatively slow and expensive in terms of memory. Method handles are supposed to be a "lightweight" way of passing around pointers to functions that the JVM has a chance of optimising. As of JDK8 method handles aren't that well optimised, and lambdas are likely to be initially implemented in terms of classes (as inner classes are).
Almost 9 years past since I've asked this question.
JDK 14 is last stable version that has massive usage of MethodHandle...
I've create mini-series of articles about invokedynamic https://alex-ber.medium.com/explaining-invokedynamic-introduction-part-i-1079de618512. Below, I'm quoting the relevant parts from their.
MethodHandle can be thought as s more powerful alternative to Core Reflection API. MethodHandle is such an Object which stores the metadata about the method (constructor, field, or similar low-level operation), such as the name of the method signature of the method etc. One way took on it is a destination of the pointer to method (de-referenced method (constructor, field, or similar low-level operation)).
Java code can create a method handle that directly accesses any method, constructor, or field that is accessible to that code. This is done via a reflective, capability-based API called MethodHandles.Lookup For example, a static method handle can be obtained from Lookup.findStatic. There are also conversion methods from Core Reflection API objects, such as Lookup.unreflect.
It is important to understand 2 key difference from Core Reflection API and MethodHandle.
With MethodHandle access check is done only once in construction time, with Core Reflection API it is done on every call to invoke method (and Securty Manager is invoked each time, slowing down the performance).
Core Reflection API invoke method is regular method. In MethodHandle all invoke* variances are signature polymorphic methods.
Basically, access check means whether you can access method (constructor, field, or similar low-level operation). For example, if the method (constructor, field, or similar low-level operation) is private, you can’t normally invoke it (get value from the field).
As opposed to the Reflection API, the JVM can completely see-through MethodHandles and will try to optimize them, hence the better performance.
Note: With MethodHandle you can also generate implementation logic. See Dynamical hashCode implementation. Part V https://alex-ber.medium.com/explaining-invokedynamic-dynamical-hashcode-implementation-part-v-16eb318fcd47 for details.

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