Win a copy of Cross-Platform Desktop Applications: Using Node, Electron, and NW.js this week in the JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

To Dr.Forman, Objection Creation Issue in Java Reflection  RSS feed

 
Ko Ko Naing
Ranch Hand
Posts: 3178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dr. Forman,
I have been hearing that Java Relection suffers from the performance issue for creating objects on-the-fly from my colleagues... I'm not sure about this in details...

Is this discussed in the chapter-9 Evaluating performance of the book? I'm wondering if I can expect that issue from the book...

Thanks a lot...
 
Nate Forman
author
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for all of your interest, Ko Ko.

Chapter 9 will show you how to do the analysis you want. It presents a careful study for how to microbenchmark operations like object creation (in our case, we use method invocation--all you'd need to do is plug in newInstance() and a constructor call instead of our invoke() and method call).

Chapter 9 also presents a methodology for how to evaluate your results using Amdahl's law. Essentially, even if a reflective call is much slower than its non-reflective counterpart, if you're doing a lot of other work in comparison, it turns out not to be significant.

Best Regards,

Nate
 
Ko Ko Naing
Ranch Hand
Posts: 3178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Nate Forman:
Chapter 9 also presents a methodology for how to evaluate your results using Amdahl's law.


Hi Nate,
By Amdahl's law, are you talking about the law that is related to parallel processors speeding up things? Could you explain a bit on how this "Amdahl's law" and the book's main topic "Java Reflection" are related to one another?

Thanks a lot for your great reply...
 
Nate Forman
author
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ko Ko,

Yep, that's the one. In parallel processor analysis, they use it to compute performance improvement--the more you have to do something, the more you improve your overall performance by making that something faster. Instead, we use it to compute performance degradation--the more you do something, the more it affects overall performance when you slow that something down.

So--you identified object creation as an issue. You want to instantiate some objects reflectively. The first thing to do is figure out how much slower the reflective version is from the static version. The next step is to figure out how much of your total work comprises constructing those specific objects. Plug those figures into Amdahl's law and you get the total slowdown for your system. If this slowdown is acceptable, put in the reflection.

I've found that understanding these concepts is helpful even if you don't do the complete analysis. Sure, we'd all like our apps to be smokin' fast, but you have to trade off other things for that. I'd rather have a "fast enough" app that I can extend and evolve easily...

Best Regards,

Nate
 
Alexandru Popescu
Ranch Hand
Posts: 995
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
afaik the performance issue of java reflection was very attentive addressed and very improved starting with jdk 1.4

--
./pope
[the_mindstorm]
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 37180
515
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ali Pope:
afaik the performance issue of java reflection was very attentive addressed and very improved starting with jdk 1.4
[the_mindstorm]

Yes. I've seen that too. In my experience the reflection hasn't contributed to the largest chunk of time anyway. The database is at least an order or magnitude slower.
 
Ko Ko Naing
Ranch Hand
Posts: 3178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Nate Forman:
So--you identified object creation as an issue. You want to instantiate some objects reflectively. The first thing to do is figure out how much slower the reflective version is from the static version. The next step is to figure out how much of your total work comprises constructing those specific objects. Plug those figures into Amdahl's law and you get the total slowdown for your system. If this slowdown is acceptable, put in the reflection.

I've found that understanding these concepts is helpful even if you don't do the complete analysis. Sure, we'd all like our apps to be smokin' fast, but you have to trade off other things for that. I'd rather have a "fast enough" app that I can extend and evolve easily...


Then there should be a trade-off between the performance degration of reflective version and the less amount of work resulting from the use of reflective version. Therefore, we cannot say which is good or bad... The only thing that matters is the nature of the problem we are going to deal with... Isn't it?

Thanks a lot for your great explanation about the issue...
 
Ko Ko Naing
Ranch Hand
Posts: 3178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ali Pope:
afaik the performance issue of java reflection was very attentive addressed and very improved starting with jdk 1.4


Was that improved in Tiger as well? Or it is still the same as it was from J2SE 1.4? :roll:

But I don't hear much about the improvement of reflection API in Tiger... Maybe it is not that critical to the upgrade to Tiger...
 
Alexandru Popescu
Ranch Hand
Posts: 995
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The performances of reflection in 1.4 are pretty amazing compared to older version. I guess for 1.5 the guys have focused on the new reflection api and not on performance.

--
./pope
[the_mindstorm]
 
Jeff Langr
author
Ranch Hand
Posts: 799
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Aside from performance, there are other reasons to resist overusing reflection. It increases complexity and can make code difficult to debug; it can make it difficult to analyze the code (particularly since you lose the ease of navigability that IDEs like Eclipse provide). For me, more specifically, the extensive use of reflection in a recent system made it very difficult to meet a customer requirement to obfuscate the code. Also, reflective code can contain defects that might otherwise be caught at compile time.

I've used reflection heavily in many circumstances, and have found it to be very effective when done carefully.

To what extent does Reflection in Action discuss coming up with a balance on the use of reflection, based on these concerns?

thanks,
Jeff
 
Alexandru Popescu
Ranch Hand
Posts: 995
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff, maybe not topic related, but I was facing this problem too no far than december. How have you solved it? Any hints?

cheers,
--
./pope
[the_mindstorm]
 
Jeff Langr
author
Ranch Hand
Posts: 799
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Greetings Ali,

Which problem? If you're referring to the obfuscation problem: I used Zelix KlassMaster, which does a pretty good job of managing reflective code. But it can only figure out so much. The solution was manual and tedious: I searched for all potential uses of reflection (e.g. getClass, use of anything from java.lang.reflect) and did a bunch of manual analysis after that in order to build the exception lists (the lists of classes and methods to not obfuscate).

As an aside, my recommendation is to not obfuscate unless you absolutely have to. There are many good reasons why it's not worth the effort (see Roedy Green's Java Glossary for a good list). So I don't view the need to obfuscate as a good reason to not use reflection.

-J-
 
Alexandru Popescu
Ranch Hand
Posts: 995
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jeff. It was a specific request from our customer. However I see that the solution is pretty much the same even if the products used for obfuscation were different (proguard in my case). In some places I have even succeeded in obfuscating classes that are used in reflection mode (dirty tricks involving conf files and great ant filter tasks ).

I agree with you that it should not be any link between using reflection and a product obfuscation (even if this lates process will require more attention).

--
./pope
[the_mindstorm]
[ January 26, 2005: Message edited by: Ali Pope ]
 
Ko Ko Naing
Ranch Hand
Posts: 3178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ali Pope:
In some places I have even succeeded in obfuscating classes that are used in reflection mode (dirty tricks involving conf files and great ant filter tasks


So Ali, don't you find it difficult to maintain your system later? Or you system is not needed to be maintained anymore after it is running without any problem?

I wish authors are involved in our cool discussion about the pros and cons of excessive usage of reflection and obfuscating classes...
 
Alexandru Popescu
Ranch Hand
Posts: 995
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here I can understand the problem in two ways:
- continuing to develop the application (which is not an issue as the obfuscation is done only for deliveries)
- maintaining the client application (and here interesting stuff may happen).

I have done the following to be able to further maintain client application:
- when building the obfuscated deliverables, we are building also an not-obfuscated version (and than placed in the deliveries CVS)
- the CVS is tagged corresponding to the deliveries CVS
- the obfuscation dictionary is kept along with the deliverables

From this point everything is running quite smooth:
- reproducing the bug on obfuscated version
- reproducing the bug on unobfuscated version (with variants: if the unobfuscted version doesn't have the issue than we use the obfuscation dictionary to find the real issue)
- fixing and delivering the patch

--
./pope
[the_mindstorm]
 
Nate Forman
author
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey Jeff (and all),

I agree that over- or mis- using reflection in an application can definitely make things more difficult. Here is a very simple example from my mistakes. In a static application, if it compiles, it's complete. This means that if you delete a class or remove a method and the app still compiles, everything's fine. Not so with reflection. Introduce dynamic loading, reflective invocation, etc. to an application, and even if it compiles, it may fail at runtime.

I've definitely had my share of reflection antipatterns, and observed several in others. We attempted to capture that experience throughout the book to help keep people from having those same difficulties.

Best Regards,

Nate
 
Lasse Koskela
author
Sheriff
Posts: 11962
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Nate Forman:
Introduce dynamic loading, reflective invocation, etc. to an application, and even if it compiles, it may fail at runtime.
That's something a good unit test suite would catch with ease
 
Nate Forman
author
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Absolutely, Lasse--and everybody should be writing good unit test suites. However, anybody who isn't should definitely be aware that misusing reflection can compound the problems that they're already having...

Nate
 
Alexandru Popescu
Ranch Hand
Posts: 995
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmmm. Thinking of the problems Jeff and myself faced during the obfuscation step and the possible problems signaled by Nate an idea just came up: a tool that statically analyse the source code and signals out all the reflection usages. It wouldn't be hard to implement it. Probably the same can be done for bytecode directly (if i think better the second solution would be even easier).

--
./pope
[the_mindstorm]
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!