I would offer +0.3 of a vote to now plan to call the next release 3.0
as a result of this.

On Fri, Mar 4, 2011 at 3:58 PM, Daniel Kulp <[email protected]> wrote:
>
>
>
> On Friday 04 March 2011 3:47:55 PM Daniel Kulp wrote:
>> I just committed the gigantic refactoring of the Spring bus stuff to base
>> it on the  ExtensionManagerBus.   I'll describe it in a minute, but first
>> the performanc result on my test case:
>>
>> Running test - 2.4.0-SNAPSHOT
>> Setup: 29105 51/sec
>> Invoke: 38174 39/sec
>> Setup config: 39026 38/sec
>>
>> Compared to the 2.3.3:
>> > Running test - 2.3.3
>> > Setup: 49732 30/sec
>> > Invoke: 62276 24/sec
>> > Setup config: 56164 26/sec
>>
>> As you can see, it's quite a bit faster across the board now.   That's
>> great. The code is also (IMO) a LOT simpler now.   We no longer have to
>> modify both bus-extension.xml and cxf-extension-blah.xml files.    The
>> extension loading is more unified.  The extension retrieval from the Bus
>> is simpler and, for the most part, identical between the Spring and
>> Non-Spring cases.    And the performance rocks.  :-)
>>
>> For the most part, it's simple to modify existing applications to work.
>> Just remove all the imports for everything except META-INF/cxf/cxf.xml
>> and META- INF/cxf/cxf-servlet.xml if you use a servlet.   However, there
>> are a couple of other "gotchas" that I encountered:
>>
>> 1) We had several files that did something like:
>>
>> <bean id="cxf" class=".... CXFBusImpl>
>>      ... conifure some interceptors....
>> </bean>
>>
>> That no longer works.   The proper way to do that has been to use the
>> <cxf:bus> namespaced object.  It's been that way for a while.  Creating
>> separate Bus's like that is just asking for having things become confused.
>> I converted all the tests to do that properly.   You COULD potentially
>> change that to:
>> <bean id="cxf" class="org.apache.cxf.bus.spring.SpringBus">
>> but using cxf:bus is definitely the better way to go.   Directly
>> instantiating and depending on internal "impl" classes and such is
>> generally a bad idea.
>>
>> 2)  depends-on and injections - since almost none of the CXF internal beans
>> are now defined in the Spring context, you cannot really depend on them
>> directly.   That's not a normal thing anyway.     The Bus is really the
>> only thing that is in the context.
>>
>> In anycase, the rest was fairly simple.   If you do define beans in the
>> spring config, they will override/replace the auto loaded stuff (just like
>> before), the configurations stuff remains the same, etc....    It just
>> starts up a ton faster and uses a bit less memory.    :-)
>>
>> I definitely have some more testing to do, but I think it's a good start.
>>
>> Dan
>>
>> On Thursday 03 March 2011 5:01:58 PM Daniel Kulp wrote:
>> > I've done quite a bit of work now on trunk to speed up the "normal" use
>> > cases. With what's on trunk now, a normal JAX-WS client that doesn't
>> > include any spring config will get the extension bus instead.   With my
>> > lastest set of changes, a default extension bus now starts up without
>> > ANY XML parsing and very few beans and such created.   This is MUCH
>> > faster now.    I wrote a little benchmark based on the java-first-jaxws
>> > example (to avoid any WSDL related things) and depending on cxf-bundle
>> > to make
>> >
>> > sure we get EVERYTHING and then does:
>> >     public static void doIteration(boolean invoke) {
>> >
>> >         BusFactory.setThreadDefaultBus(null);
>> >         BusFactory.setDefaultBus(null);
>> >
>> >         Service service = Service.create(SERVICE_NAME);
>> >         String endpointAddress = "http://localhost:9000/helloWorld";;
>> >         service.addPort(PORT_NAME,
>> >
>> >                    SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
>> >
>> >         if (invoke) {
>> >
>> >             service.getPort(HelloWorld.class).sayHi("Hello");
>> >
>> >         } else {
>> >
>> >             service.getPort(HelloWorld.class);
>> >
>> >         }
>> >
>> >     }
>> >
>> > in a loop under 3 conditions:
>> > 1) First is with invoke=false to basically time all the upfront setup
>> > costs. That includes creating the Bus, creating the Service, and then
>> > creating the Proxy.
>> >
>> > 2) Then with invoke=true to include the additional stuff of creating the
>> > interceptor chains and conduits and doing a real invoke.
>> >
>> > 3) Again with invoke=false, but this time with specifying a spring config
>> > file (cxf.xml).   This basically is the same as (1), but involves the
>> > spring Bus now.
>> >
>> > I then ran this with several versions of CXF.      Results are below.
>> > (first number is the # of ms for 1500 iterations, then it's
>> > iterations/sec)
>> >
>> > Basically, the Extension bus stuff is now a TON faster.  For 80% of the
>> > use cases, it's much faster.   I'm definitely excited about that.    The
>> > spring case slowed down a bit.  I'm not sure why.   I'll need to profile
>> > that a bit to figure it out.    In anycase, for standalone applications
>> > and cases where config is done through API's, this is quite a bit
>> > faster. As we start thinking about Blueprint and such, this can be
>> > important. Right now, the server side parts are all very spring based
>> > and thus won't benefit from this.
>> >
>> > :-(
>> >
>> > One thing I'm going to try next is making META-INF/cxf/cxf.xml just have
>> > a single bean (the ExtensionBus) and removing all the
>> > cxf-extension-*.xml files (except for the HTTP things, more in a sec on
>> > that) and seeing what happens.
>> >
>> > The HTTP stuff on the server side becomes a "challenge".   Right now, we
>> > have basically 3 implementations of the HTTPDestinationFactory:   jetty,
>> > servlet, and OSGi.    The user pretty much selects the one they want by
>> > importing the appropriate cxf-extension file and not the others in their
>> > spring config. While it works, there is a down side:  you can only have
>> > one  implementation in  you application.   Normally not a problem, but
>> > there IS the use case of a Servlet based application that may also want a
>> > service or two exposed on a specific jetty port  (like maybe for a
>> > decoupled client) that isn't under the servlet containers control.
>> >
>> > My proposal for that would be to put a single HTTPDestinationFactory in
>> > the http module that would hold onto a DestinationRegistry.   The OSGi
>> > and Servlet based things would just grab that DestinationRegistry for
>> > their dispatching. However, when the HTTPDestinationFactory is asked to
>> > create a destination for a "full" URL (like
>> > "http://localhost:8080/blah";) instead of a path (like "/blah"), it would
>> > call on a delegate that the Jetty stuff would provide to it.   I need to
>> > think about this a bit more, but I think it would work fairly well.
>> >
>> >
>> > Dan
>> >
>> >
>> >
>> >
>> > Running test - 2.4.0-SNAPSHOT
>> > Setup: 29086 51/sec
>> > Invoke: 42558 35/sec
>> > Setup config: 69839 21/sec
>> >
>> >
>> > Running test - 2.3.3
>> > Setup: 49732 30/sec
>> > Invoke: 62276 24/sec
>> > Setup config: 56164 26/sec
>> >
>> > Running test - 2.3.0
>> > Setup: 44233 33/sec
>> > Invoke: 56496 26/sec
>> > Setup config: 55305 27/sec
>> >
>> > Running test - 2.2.12
>> > Setup: 48193 31/sec
>> > Invoke: 55737 26/sec
>> > Setup config: 50582 29/sec
>> >
>> >
>> > Running test - 2.1.9
>> > Setup: 43944 34/sec
>> > Invoke: 47652 31/sec
>> > Setup config: 44550 33/sec
>> >
>> >
>> > Running test - 2.1.1
>> > Setup: 47335 31/sec
>> > Invoke: 48871 30/sec
>> > Setup config: 49255 30/sec
>
> --
> Daniel Kulp
> [email protected]
> http://dankulp.com/blog
> Talend - http://www.talend.com
>

Reply via email to