[jboss-user] [JBoss Microcontainer Development] - JBoss Reflect Performance Javassist vs Introspection
do-not-reply at jboss.com
Fri Apr 16 07:44:11 EDT 2010
Kabir Khan [http://community.jboss.org/people/kabir.khan%40jboss.com] replied to the discussion
"JBoss Reflect Performance Javassist vs Introspection"
To view the discussion, visit: http://community.jboss.org/message/537944#537944
I've attached the classes I put together for measuring this. I think I included everything needed to make them run, let me know if you have any problems. I used asm 3.2.
I haven't looked too deeply into why the performance is different, but I think it is due to how Bytecode and ConstPool make use of ByteVector and LongVector while their asm counterparts seem to modify the byte array directly. Javassist, on the other hand, needs to convert those to create the byte arrays. I have not done any measurements of this, but I guess with things the way they are that once the class bytes are parsed that javassist would be faster for calling things like getMethod() etc.?
The reason why this becomes important is that this is something that gets called huge numbers of times. However, there are other problems with this approach of generating accessors with bytecode, which means I am not 100% sure we should go with this approach. This is that we end up with:
* having to load a lot of extra classes which takes a lot of time and fills up PermGenSpace
* a lot of instances (although the number of instances probably holds true when we just use java.lang.reflect.Method instead)
My idea of creating bigger accessors isn't that viable either. If you have a class that has 300 members, but only 30 of those are used with the original method you end up with 30 small classes. With the "bigger accessor" idea, you end up with only one class, but with the code to access all 300 members, so that is a waste of memory.
If an accessor is called a lot of times it makes sense to generate a class for it. However, if it is called only a few times, then generating and loading a class for it will be slower due to having to load the class.
The main use-cases I know of are:
* Configuring the properties of the MC beans. For most bean classes I think each property is only installed once. However, in other cases, e.g. the properties of the beans for the AOP metadata + the beans installed by EJB 3 probably get accessed a lot of times, so for these it would make sense to generate classes.
* JBossXB parsing. It is used for parsing the schema, which only happens once, but when parsing the xml files, I think the accessors are used a lot.
I think we need some kind of differentiator, so that for accessors that only get called a few times we just go with norrnal reflection, but for heavily used accessors we go with generating the classes. I'll try to come up with some numbers for how many times we need to access the member for generating the class to be the cheapest option.
The question is what differentiator to use? A few ideas:
* Keep a counter in Javassist[Method/Field/Constructor]Info and once it has been called several times switch to the generated class. The problem with this is, what if this counter kicks in and we end up generating the class and then we don't have enough subsequent accesses to reap the performance benefits, i.e. in this case it would slow it down.
* Use some annotation to say that for a particular class we should always use generated members. If this annotation comes from MC BeanMetaData it could be put into the TypeInfo attachments.
I will build some statistics into JavassistConstructorInfo.newInstance(), JavassistMethodInfo.invoke() etc. so it is possible to get a report of the type of accessor used and the number of calls to help with being able to tune it using annotations unless somebody has some different ideas.
Reply to this message by going to Community
Start a new discussion in JBoss Microcontainer Development at Community
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the jboss-user