Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance impact of using CDI

I am writing a Java EE 6 web application and I am noticing a significant performance impact when using an injected object versus creating and using the object directly. The overhead appears to be of the order of 50 - 60ms per method call.

For example, using non-injected 150 method calls take approx 500ms whereas using the injected object 150 method calls take 12,000 - 13,000ms. An order of magnitude difference and then some.

Is this usual?

I am running on JBoss AS 7.1.1 final which uses Weld to handle CDI.

The injected object is defined as a singleton bean (via the javax.ejb.Singleton annotation). Could this be causing part of the problem? Or is it just the Weld proxy causing the slow down?

like image 1000
Troup Avatar asked Nov 21 '12 16:11

Troup


1 Answers

After some help from the excellent Weld forum I have discovered that:

By default, singleton session beans are transactional (section 13.3.7 of the EJB 3.1 specification) and require acquisition of an exclusive lock for every business method invocation (sections 4.8.5.4 and 4.8.5.5). In contrast, a javax.inject.Singleton is not transactional and does not support container-managed concurrency (the major consequence being that no locking scheme is implemented by the container).

If you annotate your singleton session bean with @TransactionAttribute(NOT_SUPPORTED) and @Lock(READ), you should see significantly better performance, though there may still be some overhead. If you don't need EJB features, stick with @ApplicationScoped (javax.inject.Singleton is not defined by CDI, and its semantics are therefore not governed by that specification).

https://community.jboss.org/thread/213684?tstart=0

Sadly even after annotating my EJB singleton with @TransactionAttribute(NOT_SUPPORTED) and @Lock(READ) the performance was still very poor (see timings from original post).

So the take home message is don't inject EJB Singleton session beans unless you absolutely have to and even then be aware of the performance overhead that is likely to be incurred. For methods that are rarely invoked it could be negligible but as in our case small overheads accumulate rapidly if it is a heavily used method.

We did not need the EJB features and on switching to ApplicationScoped saw order of magnitude improvements in performance of the specific method that called through to the injected bean.

like image 108
Troup Avatar answered Oct 17 '22 19:10

Troup