[hibernate-dev] Optimizing reflection optimization
Кирилл Кленский
kirill.klenski at gmail.com
Fri Jun 4 05:32:58 EDT 2010
"Could you please create a JIRA?"
JIRA ticket created: HHH-5289 Remove unnecessary security checks in property
accessors
According to the tests I have done it looks like reflection calls are taking
a lot more time compared to the direct ones - even with newest Sun JVMs and
with security checks disabled. In my opinion this means that we can benefit
from using the generated bytecode.
1. I have created a ticket HHH-5290 for enhancing the method search to the
super-classes during ReflectionOptimizer creation. Proposed patch included.
2. Optimizing single(non-bulk) property access is also an open question. I
have done an implementation of generated single property accessors and
currently we plan to use it on production.
Regards,
Kirill
2 июня 2010 г. 21:01 пользователь Steve Ebersole <steve at hibernate.org>написал:
> Ok, now that is reasonable :) And looking through the source (for Field
> at least) is does circumvent a lot of checks if accessible is set.
>
> So I can move the '!ReflectHelper.isPublic' check into the catch blocks
> to continue to error in cases where we *need* to call setAccessible; for
> other cases I'd just warn:
>
> if ( !ReflectHelper.isPublic(theClass, method) ) {
> method.setAccessible(true);
> }
>
> becomes:
>
> if ( !method.isAccessible() ) {
> try {
> method.setAccessible( true );
> }
> catch ( SecurityException se ) {
> if ( !ReflectHelper.isPublic( theClass, method ) ) {
> throw se;
> }
> else {
> log.warn( ... );
> }
> }
> }
>
> Could you please create a JIRA?
>
> On Wed, 2010-06-02 at 17:44 +0300, Кирилл Кленский wrote:
> > "We do in fact utilize setAccessible in the Hibernate code"
> >
> >
> > Yes, but if I am not mistaken only if the method/field is not public.
> > From code: !ReflectHelper.isPublic(theClass, method) )
> > method.setAccessible(true);
> > We could increase performance easily if we call setAccessible even for
> > public methods - we get rid of costly security checks.
> >
> >
> > Kirill
> >
> >
> > 2 июня 2010 г. 16:57 пользователь Steve Ebersole <steve at hibernate.org>
> > написал:
> > Perhaps. We do in fact utilize setAccessible in the Hibernate
> > code and
> > so when I did performance testing I did that as well as it
> > most closely
> > matched our actual usage. Most likely it applies the checks
> > "up front"
> > when setAccessible is called.
> >
> > I'll take a look at the test and the numbers when i have a
> > chance
> > (probably not till next week), but it is difficult to mimic
> > all the
> > variables that come into play in different server environments
> > (using
> > server versus client is only a small part).
> >
> >
> > On Wed, 2010-06-02 at 13:24 +0300, Кирилл Кленский wrote:
> > > Hi,
> > >
> > >
> > > I have done some tests that are more pure in that they do
> > not involve
> > > the application logic.
> > >
> > >
> > > Java version: jdk1.6.0_19 32-bit
> > > Results include both client and server mode tests. Numbers
> > represent
> > > 100 000 000 invocations time in milliseconds.
> > >
> > >
> > > The result format is the following:
> > > server_mode_test_time(server_mode_warmup_time) -
> > > client_mode_test_time(client_mode_warmup_time)
> > >
> > >
> > > ==========================
> > > Method access with direct call
> > > 24(4) - 69(70)
> > >
> > >
> > > Method access with reflection
> > > 815(3893) - 36 969(39162)
> > >
> > >
> > > Method access with reflection and setAccessible(true)
> > > 339(640) - 1297(1356)
> > >
> > >
> > > Method access with generated bytecode
> > > 3(2) - 646(666)
> > >
> > >
> > > Field access with reflection
> > > 40333(40016) - 40333(58800)
> > >
> > >
> > > Field access with reflection and setAccessible(true)
> > > 729(786) - 729(7696)
> > > ==========================
> > >
> > >
> > > I have the following thoughts after all:
> > >
> > >
> > > 1. Generated bytecode is comparable to direct access.
> > Strange enough
> > > that it was even faster than direct access in server mode.
> > Tests show
> > > that JVM seems to optimize reflection calls (warmup helps)
> > but the
> > > difference between reflection and direct calls is huge.
> > > 2. Setting Method.setAccessible() and Field.setAccessible()
> > to true
> > > helps to avoid security checks and increases the
> > performance. May be
> > > this is the trick Bill is talking about?
> > > This potentially could be a relatively easy way to increase
> > the
> > > performance especially if JVM is running in client mode
> > (method
> > > invocation security checks take approx 10 times more time in
> > client
> > > mode compared to server). In server mode the increase is
> > relatively
> > > small for methods (several times) and huge for fields
> > (approx 50
> > > times).
> > >
> > >
> > > I have attached the test code if somebody wants to compare
> > results.
> > > Javassist 3.8.0.GA was used to generate bytecode and is
> > required to
> > > build/run the test.
> > >
> > >
> > > Regards,
> > > Kirill Klenski
> > >
> > >
> > > 2010/5/27 Steve Ebersole <steve at hibernate.org>
> > > Perhaps it short circuits those copies and other
> > overheads if
> > > no
> > > security manager is defined (ala as in my IDE).
> > That would
> > > explain how
> > > I can see minimal improvement while Kirill sees a 4x
> > > improvement.
> > >
> > > Still rather confirm these numbers are accurate.
> > Kirill?
> > >
> > >
> > > On Thu, 2010-05-27 at 10:12 -0400, Bill Burke wrote:
> > > > Carlo deWolfe found that one of the big perf
> > problems with
> > > Java
> > > > reflection is that it is constantly doing security
> > checks
> > > with the
> > > > security manager and every get/find request makes
> > a copy of
> > > the
> > > > method/field objects. He had a hack for this, but
> > you'll
> > > have to
> > > > consult him on what it is. The JBoss Reflections
> > project
> > > might have it.
> > > >
> > > > I think once this hack is intiated, it is an
> > improvement
> > > over Javassist.
> > > > If you think about it, Java VM has to build up
> > this
> > > information anyways...
> > > >
> > > > Steve Ebersole wrote:
> > > > > I ran this same exact comparison before and I
> > seem to
> > > recall much
> > > > > different results. Unfortunately I no longer
> > have that
> > > code. This was
> > > > > part of
> > > > >
> > >
> >
> http://opensource.atlassian.com/projects/hibernate/browse/HHH-227
> > > > >
> > > > > Can you make sure you "prime" or "warm up" the
> > jvm before
> > > you start
> > > > > taking measurements?
> > > > >
> > > > > On Thu, 2010-05-27 at 15:39 +0300, Кирилл
> > Кленский wrote:
> > > > >> Hi,
> > > > >>
> > > > >> My measurements have indicated that there is a
> > > performance gain. I have
> > > > >> measured the time spent in setPropertyValues
> > and
> > > getPropertyValues.
> > > > >> The optimized version was 4 times faster in
> > these methods
> > > giving an
> > > > >> estimated application performance increase of
> > about 3%.
> > > > >> Optimizing getPropertyValue and
> > setPropertyValue could
> > > give 1.5% more
> > > > >> according to our rough calculations.
> > > > >>
> > > > >> Kirill
> > > > >>
> > > > >> 26 мая 2010 г. 23:53 пользователь Emmanuel
> > Bernard
> > > > >> <emmanuel at hibernate.org>написал:
> > > > >>
> > > > >>> Hi,
> > > > >>> Have you noticed a perf difference in your
> > application
> > > with and without the
> > > > >>> patch?
> > > > >>> I am wondering if modern VMs have catched up
> > with what
> > > Javassist does.
> > > > >>>
> > > > >>> On 26 mai 2010, at 18:29, Кирилл Кленский
> > wrote:
> > > > >>>
> > > > >>>> 1. I have noticed that
> > > > >>>>
> > >
> >
> org.hibernate.bytecode.javassist.BulkAccessorFactory.findAccessors(...)
> > > > >>> is
> > > > >>>> searching for accessor methods in the
> > optimized entity
> > > class only. This
> > > > >>>> means that the methods from the superclasses
> > are not
> > > visible during
> > > > >>>> BulkAccessor creation unless overridden by
> > child
> > > classes. By enhancing
> > > > >>> the
> > > > >>>> algorithm to search down the inheritance tree
> > we could
> > > avoid creation of
> > > > >>>> redundant methods which increase the code
> > verbosity a
> > > lot. In our case
> > > > >>>> almost all the entities are inherited from
> > the base
> > > classes having the
> > > > >>>> common entity properties defined, so the
> > reflection
> > > optimization does not
> > > > >>>> work for any of them until we override the
> > inherited
> > > methods in all the
> > > > >>>> child classes. The implementation is trivial,
> > but I
> > > have got a ready
> > > > >>>> prototype if anybody is interested.
> > > > >>>
> > > > >> _______________________________________________
> > > > >> hibernate-dev mailing list
> > > > >> hibernate-dev at lists.jboss.org
> > > > >>
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
> > > > >
> > > > >
> > > >
> > >
> > >
> > > --
> > >
> > >
> > > Steve Ebersole <steve at hibernate.org>
> > > http://hibernate.org
> > >
> > >
> > >
> > >
> >
> >
> >
> > --
> >
> > Steve Ebersole <steve at hibernate.org>
> > http://hibernate.org
> >
> >
> >
>
>
> --
> Steve Ebersole <steve at hibernate.org>
> http://hibernate.org
>
>
More information about the hibernate-dev
mailing list