Camel
  1. Camel
  2. CAMEL-5675

Camel Route Startup Performance Slow

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.8.6
    • Fix Version/s: 2.11.0
    • Component/s: camel-core
    • Labels:
    • Environment:

      JDK 1.6

    • Estimated Complexity:
      Novice

      Description

      I am writing unit tests for Camel and found that each unit test was taking up to a second just to create the Camel routes. That's not very long, but we have a large unit test suite that needs to run quickly.

      I did a performance profile and found that most of the time is going to the method org.apache.camel.util.IntrospectionSupport.getProperties(Object, Map, String). That method, then also calls IntrospectionSupport.isSetter(Method), and just running two unit tests I saw isSettter called 2.5 million times!

      It seems to me that a cache per class of the properties would make a huge performance improvement on Camel route building.

      1. CAMEL-5675.patch
        20 kB
        Claus Ibsen
      2. before.png
        101 kB
        Claus Ibsen
      3. after.png
        121 kB
        Claus Ibsen

        Activity

        Hide
        Claus Ibsen added a comment -

        I asume you have JMX enabled as well, as it does a fair bit of introspection as well.

        Show
        Claus Ibsen added a comment - I asume you have JMX enabled as well, as it does a fair bit of introspection as well.
        Hide
        Claus Ibsen added a comment -

        Yeah I think we could have caching during startup of CamelContext. Having cache at runtime is a bit more problematic, as you would need to be able to limit the cache size. And as well have soft reference to avoid classloader issues etc.

        Its easier to cache during startup only (and during shutdown as well) as we can control when caching is enabled/disable.

        Show
        Claus Ibsen added a comment - Yeah I think we could have caching during startup of CamelContext. Having cache at runtime is a bit more problematic, as you would need to be able to limit the cache size. And as well have soft reference to avoid classloader issues etc. Its easier to cache during startup only (and during shutdown as well) as we can control when caching is enabled/disable.
        Hide
        David J. M. Karlsen added a comment -

        You could maybe use commons which has introspection cache already?
        http://commons.apache.org/beanutils/xref/org/apache/commons/beanutils/PropertyUtils.html

        Show
        David J. M. Karlsen added a comment - You could maybe use commons which has introspection cache already? http://commons.apache.org/beanutils/xref/org/apache/commons/beanutils/PropertyUtils.html
        Hide
        Claus Ibsen added a comment -

        Well even with some caching it only speedup for very big routes.

        Les, can you tell us a bit about your setup? How many tests do you run? Do you have many routes, and are they small/big etc?
        And do you have JMX enabled during testing?

        For the Camel tests of itself there is hardly a speedup (many small route tests). And most tests have disabled JMX.

        For a big route with 1000 nodes and JMX enabled, I could cut down startup time with 1.5-2s. But just wonder who would have such big routes?

        Show
        Claus Ibsen added a comment - Well even with some caching it only speedup for very big routes. Les, can you tell us a bit about your setup? How many tests do you run? Do you have many routes, and are they small/big etc? And do you have JMX enabled during testing? For the Camel tests of itself there is hardly a speedup (many small route tests). And most tests have disabled JMX. For a big route with 1000 nodes and JMX enabled, I could cut down startup time with 1.5-2s. But just wonder who would have such big routes?
        Hide
        Claus Ibsen added a comment -

        I have attached a patch which has caching on JMX and IntrospectionSupport.

        The most noticeable performance improvements is when JMX is enabled, and if you have large routes.

        The big route tests is about cut down from 8s to 4s on startup (looking at the startup time Camel reports itself).

        Show
        Claus Ibsen added a comment - I have attached a patch which has caching on JMX and IntrospectionSupport. The most noticeable performance improvements is when JMX is enabled, and if you have large routes. The big route tests is about cut down from 8s to 4s on startup (looking at the startup time Camel reports itself).
        Hide
        Claus Ibsen added a comment -

        David,

        Thanks for the link. There is although already a cache in Camel we can leverage, LRUSoftCache.

        Show
        Claus Ibsen added a comment - David, Thanks for the link. There is although already a cache in Camel we can leverage, LRUSoftCache.
        Hide
        Claus Ibsen added a comment -

        Screenshot from profiler with full tracing enabled.

        Running the big route test (lowered to 500, instead of 1000 nodes)

        Apache Camel (CamelContext: camel-1) started in 4.958 seconds

        Show
        Claus Ibsen added a comment - Screenshot from profiler with full tracing enabled. Running the big route test (lowered to 500, instead of 1000 nodes) Apache Camel (CamelContext: camel-1) started in 4.958 seconds
        Hide
        Claus Ibsen added a comment -

        after screenshot with patch.

        Notice the much lower invocation count, and the self time is also much lower.

        Apache Camel (CamelContext: camel-1) started in 2.447 seconds

        Show
        Claus Ibsen added a comment - after screenshot with patch. Notice the much lower invocation count, and the self time is also much lower. Apache Camel (CamelContext: camel-1) started in 2.447 seconds
        Hide
        Claus Ibsen added a comment -

        Should be faster now, and no longer so high invocation counts.

        Show
        Claus Ibsen added a comment - Should be faster now, and no longer so high invocation counts.
        Hide
        Les Novell added a comment -

        Wow, thank you Claus. I was off work yesterday & surprised to come back today and see this issue already addressed I will definitely give the changes a try & report back the results.

        I agree that the overall performance is generally OK. It was taking 1/2 - 1 sec to initialize our routes. We were also applying advice in order to mock out certain routes, which causes the routes to be stopped and restarted. All this caused a unit test to take 1-2 seconds on average. We try and target our unit tests to run in <1/10 second, since our unit test suite is large (1200+ tests).

        Your fix to the Introspection classes should help immensely.

        Much Thanks,
        Les

        Show
        Les Novell added a comment - Wow, thank you Claus. I was off work yesterday & surprised to come back today and see this issue already addressed I will definitely give the changes a try & report back the results. I agree that the overall performance is generally OK. It was taking 1/2 - 1 sec to initialize our routes. We were also applying advice in order to mock out certain routes, which causes the routes to be stopped and restarted. All this caused a unit test to take 1-2 seconds on average. We try and target our unit tests to run in <1/10 second, since our unit test suite is large (1200+ tests). Your fix to the Introspection classes should help immensely. Much Thanks, Les
        Hide
        Claus Ibsen added a comment -

        If you run Camel 2.9+ then in the unit tests you can tell Camel that you use advice with, as said in the green box at
        http://camel.apache.org/advicewith.html

        That should avoid the restart of routes.

        Show
        Claus Ibsen added a comment - If you run Camel 2.9+ then in the unit tests you can tell Camel that you use advice with, as said in the green box at http://camel.apache.org/advicewith.html That should avoid the restart of routes.
        Hide
        Claus Ibsen added a comment -

        I did change the cache to use weak reference based. So if you have already run some tests, then try again with latest code from trunk.

        Show
        Claus Ibsen added a comment - I did change the cache to use weak reference based. So if you have already run some tests, then try again with latest code from trunk.

          People

          • Assignee:
            Claus Ibsen
            Reporter:
            Les Novell
          • Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development