2

The Example

I'm writing an utility to transform domain classes, pojos and pogos in CSV, using OpenCSV. The example that I created is available on git.

The idea is to go to the index action of the TestController and hit the button that will make an ajax call. This ajax will transform all instances of the domain class Test, created on bootstrap, in CSV and return this text to the view.

The flow

  • Bootstrap creates 5000 records of domain class Test
  • User go to index page: /csv-example/test/index
  • User hit the button, making ajax request
  • Controller list all Test records
  • Controller transform ArrayList in a String csv formatted
    • DefaultCSVConverter will look for the serializer for the class Test
    • DomainClassSerializer will transform the instance in List<String[]>
    • DefaultCSVConverter will use OpenCSV to write the List<String[]>

The Problem

Grails is much faster if I run this example app in production mode, and I'm trying to understand why. I already tried to run in dev mode, disabling the realoding agent:

grails Ddisable.auto.recompile=true -noreloading run-app

This makes no difference in the time spent to transform the instances.

So my question is: beside the reloading agent, what more can make this performance different between development and production modes?

The Env

Grails 2.2.1

Win 7 x64

JDK 1.6.0_43 64 bits

Community
  • 1
  • 1
  • This is interesting question. Not exactly sure your answer but another thing that is enabled on dev is showSource attribute support per Jeff Brown's comment in this link http://grails.1312388.n4.nabble.com/Grails-development-vs-production-td4637185.html – Alidad Apr 12 '13 at 19:37
  • Who anyone that marked as a "not a real question", please specify what you think that's missing. I'm looking, at least, to bring up the differences between dev and prod that can impact in performance. –  Apr 12 '13 at 19:48

3 Answers3

2

It seems that the difference is caused by the internationalization. PluginAwareResourceBundleMessageSource have different performances between dev and prod running modes. To find that I used Jvisualvm, profiling CPU in development and production modes.

To start Grails

set GRAILS_OPTS=-Xverify:none -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8500 -Dcom.sun.management.jmxremote.authenticate=false -

grails  -Ddisable.auto.recompile=true -noreloading run-app

To start jvisualvm

jvisualvm -J-Xms1G -J-Xmx1G –cp:a path/to/app/target/classes

The profiling result should look like this

enter image description here

0

I looked at your github code, and prod dataSource - pooled=true? Could this do it?

DAJ
  • 96
  • 2
  • I think that's not the cause, since I just do one query: `Test.findAll()`. The difference is the time that the conversion of the domain list to csv took. But thanks for looking the code :-) –  Apr 12 '13 at 21:51
  • So, now I 'really' looked at the code, and I am curious - are you sure findAll() is returning the same collection size in qa vs prod? And, if it's not on the read side, how about the write side - is this doing i/o to the browser? – DAJ Apr 12 '13 at 22:39
  • Checked the size, it's the same. What do you mean with "i/o to the browser"? –  Apr 13 '13 at 00:04
0

My understanding is that prod and dev differ mostly in what is defined in grails-app/conf, with respect to the application executable. Assuming you had same hardware/os configurations and start-up params for both prod and dev, I would start by looking at what's different in your config files.

Your Config.groovy

environments {
    development {
        grails.logging.jul.usebridge = true
    }
    production {
        grails.logging.jul.usebridge = false
        // TODO: grails.serverURL = "http://www.changeme.com"
    }
}

DataSource.groovy

development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
        }
}
...
production {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
            pooled = true
            properties {
               maxActive = -1
               minEvictableIdleTimeMillis=1800000
               timeBetweenEvictionRunsMillis=1800000
               numTestsPerEvictionRun=3
               testOnBorrow=true
               testWhileIdle=true
               testOnReturn=true
               validationQuery="SELECT 1"
            }
        }
}

One thing that stands out (correct if I'm wrong, it's been awhile since I config datasource for H2) is that in dev, you're running H2 in-memory, whereas in prod you're writing to disk.

ikumen
  • 11,275
  • 4
  • 41
  • 41
  • Fair enough, I updated the code, with config.groovy and datasource.groovy adjusted, nothing changed in the time. I think that's more than just configuration that differs from dev and prod. Check @Alidad link, for example. –  Apr 13 '13 at 00:00