You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Daniel Kulp <dk...@apache.org> on 2011/03/03 23:01:58 UTC

Startup speed, XML, etc.....

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


Re: Startup speed, XML, etc.....

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Dan

Some comments on the HTTP...

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.
>
>
I'd like to propose to view this refactoring in the context of the future
OSGI enhancements in general, particularly the one related to the http-osgi
transport. I feel there's an opportunity to make the http-osgi transport
deprecated which is mostly duplicating the http transport code, assuming we
can figure out how to make the whole CXF play nicely and more pro-actively
in OSGI. If we manage to have a top-level Activator (in trunk/distribution)
delegating to individual Activators (http, jaxws, jaxrs, and other key
modules) then in case of the HTTP transport it can follow a pure and
straight-forward OSGI way to get OSGI HTTP service, register as a servlet,
make itself configurable via Config manager, etc and make it all as dynamic
as it is in DOSGI...

thanks, Sergey


> 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
>
>



-- 
Sergey Beryozkin

Application Integration Division of Talend <http://www.talend.com>
http://sberyozkin.blogspot.com

Re: Startup speed, XML, etc.....

Posted by Benson Margulies <bi...@gmail.com>.
this makes sense to me.

Re: Startup speed, XML, etc.....

Posted by Guillaume Nodet <gn...@gmail.com>.
On Mon, Mar 7, 2011 at 16:09, Daniel Kulp <dk...@apache.org> wrote:
> On Friday 04 March 2011 4:23:34 PM Benson Margulies wrote:
>> I would offer +0.3 of a vote to now plan to call the next release 3.0
>> as a result of this.
>
> Well, for a 3.0, I'd like to do a LOT more than this, but I don't have time
> right now (more in a second).     Thus, what I'm going to do:
>
> Restore the META-INF/cxf/cxf-extension-*.xml files.  Instead of definining the
> beans directly, I'm going to replace them with a factory bean that would look
> the been up from the Bus as well as log a "this usage is deprecated" type
> warning.       Thus, for 2.4, it will work and be marked deprecated, we can
> remove it in 3.0.   Does that make sense?   This should allow existing stuff
> to work fine OTHER than the CXFBusImpl thing which should never have been done
> in the first place (usage of internal impl class) yet provide users with the
> knowledge that it's deprecated and unneeded.   The default bus wouldn't pick
> these up anyway (only if the user actually imports them) so it would not
> affect my benchmarks below.
>
>
> One we get 2.4 out, I definitely think targetting a 3.0 would be a good thing.
> The stuff I'd like to get done (and I'll stick this on a wiki page) includes:
>
> 1) Combine common-utilities/api/core into just a cxf-kernel or similar.
>
> 2) Pull the "wsdl" specific stuff from kernel into a webservices base package
> that the webservices related things can pull and jaxrs doesn't have to.
>
> 3) Resolve all the split package things that prevent the OSGi bundling from
> working well.
>
> 4) Likely move some of the other Abstract classes and such from kernel.   For
> example, we now have a transports-common module.   Move the
> AbstractDestination and stuff there.
>
> 5) Go through all the @Deprecated things and remove them.   Likewise, remove
> unused method params (I know there are a couple on the Destination API) and
> such.
>
> 6) POSSIBLY update various API's to pass in the Bus (or other objects) if
> needed instead of holding it as an instance variable.   That would allow
> singleton instances for things like the transports and such.   For example, it
> would be good to register a "FooCXFTransport" as an OSGi service that we could
> lookup later.   Right now, we couldn't do that unless you only used a global
> bus, which isn't exactly what the purpose of the Bus is.

Not if the use of singletons is better or not in that case, but for
the OSGi side, one way would be register a factory.
That's what we have in Camel where the camel-core bundle will register
an OSGi service ComponentResolver with some associated properties when
a bundle providing component is deployed.  The CamelContext can then
look up the component factories in OSGi.  The component factory could
use a singleton internally, but that's a different problem.

>
>
> I'm sure we can come up with a lot more things as well...  :-)
>
> Dan
>
>
>
>
>> On Fri, Mar 4, 2011 at 3:58 PM, Daniel Kulp <dk...@apache.org> 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
>> > dkulp@apache.org
>> > http://dankulp.com/blog
>> > Talend - http://www.talend.com
>
> --
> Daniel Kulp
> dkulp@apache.org
> http://dankulp.com/blog
> Talend - http://www.talend.com
>



-- 
Cheers,
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
Open Source SOA
http://fusesource.com

Re: Startup speed, XML, etc.....

Posted by Daniel Kulp <dk...@apache.org>.
On Friday 04 March 2011 4:23:34 PM Benson Margulies wrote:
> I would offer +0.3 of a vote to now plan to call the next release 3.0
> as a result of this.

Well, for a 3.0, I'd like to do a LOT more than this, but I don't have time 
right now (more in a second).     Thus, what I'm going to do:

Restore the META-INF/cxf/cxf-extension-*.xml files.  Instead of definining the 
beans directly, I'm going to replace them with a factory bean that would look 
the been up from the Bus as well as log a "this usage is deprecated" type 
warning.       Thus, for 2.4, it will work and be marked deprecated, we can 
remove it in 3.0.   Does that make sense?   This should allow existing stuff 
to work fine OTHER than the CXFBusImpl thing which should never have been done 
in the first place (usage of internal impl class) yet provide users with the 
knowledge that it's deprecated and unneeded.   The default bus wouldn't pick 
these up anyway (only if the user actually imports them) so it would not 
affect my benchmarks below.


One we get 2.4 out, I definitely think targetting a 3.0 would be a good thing.   
The stuff I'd like to get done (and I'll stick this on a wiki page) includes:

1) Combine common-utilities/api/core into just a cxf-kernel or similar.

2) Pull the "wsdl" specific stuff from kernel into a webservices base package 
that the webservices related things can pull and jaxrs doesn't have to.

3) Resolve all the split package things that prevent the OSGi bundling from 
working well.

4) Likely move some of the other Abstract classes and such from kernel.   For 
example, we now have a transports-common module.   Move the 
AbstractDestination and stuff there.

5) Go through all the @Deprecated things and remove them.   Likewise, remove 
unused method params (I know there are a couple on the Destination API) and 
such.

6) POSSIBLY update various API's to pass in the Bus (or other objects) if 
needed instead of holding it as an instance variable.   That would allow 
singleton instances for things like the transports and such.   For example, it 
would be good to register a "FooCXFTransport" as an OSGi service that we could 
lookup later.   Right now, we couldn't do that unless you only used a global 
bus, which isn't exactly what the purpose of the Bus is.   


I'm sure we can come up with a lot more things as well...  :-)

Dan




> On Fri, Mar 4, 2011 at 3:58 PM, Daniel Kulp <dk...@apache.org> 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
> > dkulp@apache.org
> > http://dankulp.com/blog
> > Talend - http://www.talend.com

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog
Talend - http://www.talend.com

Re: Startup speed, XML, etc.....

Posted by Benson Margulies <bi...@gmail.com>.
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 <dk...@apache.org> 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
> dkulp@apache.org
> http://dankulp.com/blog
> Talend - http://www.talend.com
>

Re: Startup speed, XML, etc.....

Posted by Daniel Kulp <dk...@apache.org>.
One more thing....

Of course, the most important thing from all this work is...

What affect does it have on the time to build CXF?  After all, it's all about 
me....   :-)

Running "mvn -T 8 -Pnochecks" from a prebuilt tree on my 4 core laptop:

2.3.x branch:
[INFO] BUILD SUCCESS
[INFO] 
------------------------------------------------------------------------
[INFO] Total time: 11:04.667s (Wall Clock)


Trunk:
[INFO] BUILD SUCCESS
[INFO] 
------------------------------------------------------------------------
[INFO] Total time: 9:45.506s (Wall Clock)


And trunk has extra stuff like the jibx databinding and the logbrowser stuff.  

Super cool.  I haven't seen CXF build and test in under 10 minutes in a VERY 
long time.   Now we can all be 10% more productive.    :-)


Dan




On Friday 04 March 2011 3:58:42 PM Daniel Kulp wrote:
> I forgot to mention one other huge advantage to all of this...
> 
> One of the issues I keep having when deeling with customers and new users
> and such, expecially of some of the advanced things, is the question of
> "what META-INF/cxf/ files do I need to import for my application?"   
> We've done a pretty poor job of documenting exactly what you need and
> when.     For example, I know when Dennis was writing his dev works
> articles, he sent me a couple test cases that were not working, but adding
> additional imports in (for things like ws-a and such) just made them work.
> 
> Now they are all gone.   :-)     Just import cxf.xml and, if in a servlet
> environment, cxf-servlet.xml  (for now, I want to get rid of that next).
> Done.   Everything just works.  :-)
> 
> A techical/code solution to a documentation problem.  That's kind of
> backwords.  :-)
> 
> 
> Dan
> 
> 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
dkulp@apache.org
http://dankulp.com/blog
Talend - http://www.talend.com

Re: Startup speed, XML, etc.....

Posted by Dennis Sosnoski <dm...@sosnoski.com>.
On 03/05/2011 09:58 AM, Daniel Kulp wrote:
> ...
>
> Now they are all gone.   :-)     Just import cxf.xml and, if in a servlet 
> environment, cxf-servlet.xml  (for now, I want to get rid of that next).   
> Done.   Everything just works.  :-)
>
> A techical/code solution to a documentation problem.  That's kind of 
> backwords.  :-)
>   

Documentation is sometimes just a patch for usability issues, and
solving the underlying issue beats documenting how to work with the
existing code. :-)

A very nice restructuring, however you choose to frame it!

  - Dennis


Re: Startup speed, XML, etc.....

Posted by Daniel Kulp <dk...@apache.org>.
I forgot to mention one other huge advantage to all of this...

One of the issues I keep having when deeling with customers and new users and 
such, expecially of some of the advanced things, is the question of "what 
META-INF/cxf/ files do I need to import for my application?"    We've done a 
pretty poor job of documenting exactly what you need and when.     For 
example, I know when Dennis was writing his dev works articles, he sent me a 
couple test cases that were not working, but adding additional imports in (for 
things like ws-a and such) just made them work.     

Now they are all gone.   :-)     Just import cxf.xml and, if in a servlet 
environment, cxf-servlet.xml  (for now, I want to get rid of that next).   
Done.   Everything just works.  :-)

A techical/code solution to a documentation problem.  That's kind of 
backwords.  :-)


Dan



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
dkulp@apache.org
http://dankulp.com/blog
Talend - http://www.talend.com

Re: Startup speed, XML, etc.....

Posted by Daniel Kulp <dk...@apache.org>.
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
dkulp@apache.org
http://dankulp.com/blog
Talend - http://www.talend.com

Re: Startup speed, XML, etc.....

Posted by Christian Schneider <ch...@die-schneider.net>.
Sounds interesting. I am currently working on the camel-servlet module 
and thought about the same thing.
At the moment in camel servlet: is used to indicate a servlet based 
server. While jetty: is used for a jetty based.
I thought to use only http and choose based on full url with server 
(jetty) or without (servlet).

For the moment my focus is on removing the timing problem when creating 
a servlet in web.xml and a endpoint in spring.
I also solved it with a HttpRegistry. Unlike in CXF servlets and 
consumers both register with it and it connects both.
So this works a bit like the whiteboard pattern.

Btw. I think at the moment in CXF we use the whiteboard extender to 
register the osgi http servlet.
The problem with this is that it runs only with pax web. Should we do 
something about this?

Christian


Am 03.03.2011 23:01, schrieb Daniel Kulp:
> 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
>
>

-- 
----
http://www.liquid-reality.de