[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