Вопрос

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

Это было полезно?

Решение

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

Другие советы

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

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top