This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
Just looking for opinions on the tradeoff between the performance of reflection and the convenience of using it. All major web frameworks use Reflection throughout. Obviously this makes things much easier for the developer but is there a tradeoff? If an application that utalized say Spring/Struts/Hibernate used zero reflection, would the app perform better? (Pretend the code used in lue of reflection was very well written). Or is the performance loss negligable?
I don't know the precise tradeoffs, so I can't answer your question directly. But, have you thought about adding interfaces to a lot of your classes? I know in lot of situations where I've considered using reflection, I've instead set up a public interface and worked off that.
Originally posted by Scott Selikoff: I don't know the precise tradeoffs, so I can't answer your question directly. But, have you thought about adding interfaces to a lot of your classes? I know in lot of situations where I've considered using reflection, I've instead set up a public interface and worked off that.
Well, I am not sure how interfaces negate the need for reflection. But thanks for the note.
Come to think of it, I do understand what you are saying. But that was part of my (Pretend the code used in lue of reflection was very well written). I am not looking for solutions to use instead Reflection. Just opinions on the tradeoffs.
The cost of reflection is known to be very low in modern JVMs. It's unlikely to be the bottleneck when you compare it to the costs of transmitting information via http or accessing a database...
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Originally posted by Ilja Preuss: The cost of reflection is known to be very low in modern JVMs. It's unlikely to be the bottleneck when you compare it to the costs of transmitting information via http or accessing a database...
Got anything to back that up? Links, documents, etc?
I have never found reflection-using code to be "convenient". It's quite hard to understand and get right, in my opinion. So this equivalent non-reflection code would have to be quite ugly for reflection to beat it out. That's from the code-writing and code-maintaining point of view. I can't comment on the performance question, knowing nothing about the actual code.
Originally posted by Paul Clapham: I have never found reflection-using code to be "convenient". It's quite hard to understand and get right, in my opinion. So this equivalent non-reflection code would have to be quite ugly for reflection to beat it out. That's from the code-writing and code-maintaining point of view. I can't comment on the performance question, knowing nothing about the actual code.
Writing the code is never convenient. Using the code once it's written is usually quite convenient. Spring, for example...very convenient and quite reflection heavy. I don't want to argue the power of that API. But imagine a system built using spring (reflection) and the same system built without spring (no reflection). Can an argument be made that the non-spring system would performe better (again, given well written code). It's already a given that the Spring'd system is going to be easier to maintain and was probably developed quicker. But that is not a factor in this discussion. And note too that I only said Spring because it's well known. Replace Spring with any technology that uses reflection heavily. I am not picking on anyone. [ December 14, 2005: Message edited by: Gregg Bolinger ]
Architects don't expect maintenance on translation layer. Once a translation layer is written it may remain so or replaced with another. It is rare to enhance a translation layer. Translation layer is normally built using reflection to make it more flexible.
Most of the refactoring occurs in no-translation layer code. When business rules change refactoring may become mandatory. A class hierarchy may be broken to introduce a new feature. Or a pattern may be introduced, removed or replaced.
One major step while doing refactoring is to analyze where all a type, a method or a variable is used. In such an analysis a crucial part is played by 'how a type/method/variable is used'. While using reflection either or all of type/method/variable can be represented in String literals or in a properties file. Because reflection uses String, it is difficult to know what are the type/method/variable 's being used.
Even by using Tools like Lucene this analysis will fail in reflection based code.
Reflection is generally slower than normal code.
Below are some of my anti-reflection arguments. 1. A code having reflection is difficult to refactor. 2. A code having reflection is not maintenance friendly. 3. Though a reflective code may compile it's logical compilation occurs at run time when you see NoSuchMethodException. 4. Reflection breaks many contracts. Any of the access modifiers of a method have value. 5. Reflection is slow. ( I don't know the case with new JRE's after 1.4)
Below are some scenarios where I recommend reflection 1. You have no other choice than reflection. 2. A small subsystem which may not change often. 3. Have human Resources to support the code for long time.
I'd agree with most of the above, except performance which I've found is a bit of a myth with newer JREs. I know this is just anecdotal, rather than actual performance statistics, but we use reflection a lot in the application I currently work on and don't suffer poor performance. The fact that reflection features in many frameworks these days should be an indication that it performs at least well enough. And when was the last time anyone actually got a defined non-functional requirement of "this application must manage X transactions per whatever" or "this application must respond subsecond for X concurrent users"? I know it does happen, and I don't suggest people are cavalier when it comes to writing non-performant code, but I do think it is very much over emphasized.
Anyway, back on topic. The real cost of reflection is maintenance and testing. It is very easy to break an application that uses reflection by changing method signatures. Reflection does undermine the cast-iron, unavoidable test of the compiler, and replace it with the need for good unit and system tests. [ December 15, 2005: Message edited by: Paul Sturrock ]
We use reflection instead of writing equals methods for all our objects. (and of course in Struts and the like.) This has never been the bottleneck - that was always the database as Ilja mentioned.
I think 3rd party libraries are a great place to use reflection. Someone else maintains it and it is likely to be a stable interface. That said, we do use explicit ActionForms rather than DynaForms because compile time safety makes development faster.
[edited to fix spelling of reflection] [ December 15, 2005: Message edited by: Jeanne Boyarsky ]
And when was the last time anyone actually got a defined non-functional requirement of "this application must manage X transactions per whatever" or "this application must respond subsecond for X concurrent users"?
Ok, you actually figured out the reason for this thread. This is exactly why I am inquiring about this. I really apprerciate all the information so far but my main question seems to be being avoided.
Can an argument be made that the zreo reflection system would perform better (again, given well written code) than an app the relied heavily on reflection?
Reflective access is slower than directly calling a method; no matter how optimized, at the micro level there's always a little more work. Even assuming that the initial work of getting ahold of Class and Method objects and invoking Construtors and whatnot is amortized over a long runtime, and assuming that you do a great job of using reflection optimally by reusing Method objects and argument arrays and the like, the act of invoking a single Method will always involve putting the arguments into an Object, then calling Method.invoke(), which has to retrieve the arguments, possibly unbox them, check them, then invoke the underlying method. There's no way around the fact that this involves a finite amount of overhead.
Now, that said, this finite amount is not huge. I wrote this little program which calls a method 100,000 times non-reflectively, then reflectively. When I run it on my machine, it prints, roughly, "2\n200\n225\n". This is pretty close to measuring the pure overhead of calling a method reflectively, as the method does nothing. 200 milliseconds for 100,000 calls is 2 microseconds per call. For comparison's sake, you see that creating 100,000 Strings and putting them in an ArrayList is taking 225 milliseconds, 2.25 microseconds per call. Now, don't go telling me how microbenchmarks are bad -- I know. But this gives us some kind of rough idea, anyway.
So let's take that as the benchmark. Let's say you must be able to service 100,000 concurrent users and that serving one customer is going to take 20 reflective calls. That's 4 extra seconds of CPU time to process 100,000 requests. How many trips to the database will you make, and how much time will they take? How much file I/O? How long does that take? For that matter, how many objects do you create to service a request?
So, my very long winded answer is that yes, you can make that argument. But the performance hit is really quite small in the grand scheme of things, and there are much more important considerations.
Thanks Ernest. That is more what I was looking for. I made a similar test case and had similar results. Although I found the results to be a bit less neglagable than you did. But that is just a difference of opinion.
See, I am thinking about this a bit differently. As developers we are very concerned with the development process. We strive to make things easier on us as we go along. And it is my opinion that at times, we may sacrifice performance for that very cause. Now, in todays world of cheap hardware I'll concede that performance isn't on the front burner like it used to be when we had 64k total memory to work with. We can throw all sorts of data out in memory and not really worry too much about it. We can rely on the 64 bit 3 GHz processor to crunch our code at lightning speed. And this is great. And probably 90% of the applications we develop can handle the case for reflection and various other bottlenecks like database queries and http.
With all that being said developers today have so many more development tool options that we didn't have even 5 years ago. Look how far Eclipse has come in just that short amount of time, as 1 example. There are little things like manually typing out 50 getters and setters for a javabean that just take a keystroke or 2 now. There are many ways in which the speed of our development process has been improved. And it is my opinion that as the simple things get even simpler, we should step back and look at where we think we are saving so much development time by using fancy API's and then review what it is really saving us.
I am saying step away from the development process. Just look at the end result. Ignore the fact that by using Spring and Hibernate you saved 2 months of development time. At the end, the project is done, the system works exactly the same. Now does performance matter? I think it should. I say the less bottlenecks the better.
And now I will move this to the Performance forum because I think it will fit better there.