March 21, 2008

Spring2.5はどのぐらいパフォーマンスが向上したのか?

仕事で、あるお客様に「Spring2.5は2.0からどのぐらい変わったのか?」と聞かれました。Spring2.5は2.0よりパフォーマンスが大幅にアップしたと言われていますが、私自身いったいどのぐらい向上したのかを具体的に知らなかったので、簡単なサンプルを使って検証してみました。

  • 検証したマシン: Lenovo Tinkpad X60
  • CPU: Core2 DUO T7200 2.00GHz
  • RAM: 2GB
  • Windows XP Professional SP2
  • Sun JavaSE JDK 1.6.0_05
  • Eclipse 3.3 Europa
まず用意したのは、あまりにも簡単なこんなサンプル。

[ParentBeanImpl.java]

package springtest.bean;

public class ParentBeanImpl {
}



[applicationContext.xml]

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <bean id="parentBean" class="springtest.bean.ParentBeanImpl" />

</beans>



これで、ひたすら getBean("parentBean") を、100万回 * 100セットして、100万回の実行にかかった時間の平均値を求めてみました。

[SampleMain.java]

package springtest;

import springtest.bean.ParentBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SampleMain {

    private static final int count = 1000000;
    private static final int set = 10;

    public static void main(String[] args) {

        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "applicationContext.xml");

        for (int i = 0; i < set; i++) {
            for (int j = 0; j < count; j++) {
                ctx.getBean("parentBean");
            }
        }
    }
}



Spring2.0.8 442ミリ秒
Spring2.5.2 234ミリ秒

Spring2.5は、2.0に比べて2倍近くパフォーマンス向上していることがわかります。


次に、DIありで。

[ParentBeanImpl.java]

package springtest.bean;

public class ParentBeanImpl {

    private ChildBean childBean;

    public void setChildBean(ChildBean childBean) {
        this.childBean = childBean;
    }
}



[ChildBean.java]

package springtest.bean;

public interface ChildBean {
}



[ChildBeanImpl.java]

package springtest.bean;

public class ChildBeanImpl implements ChildBean {
}



[applicationContext.xml]

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <bean id="parentBean"
        class="springtest.bean.ParentBeanImpl">
        <property name="childBean">
            <ref bean="childBean" />
        </property>

    </bean>
    <bean id="childBean"
        class="springtest.bean.ChildBeanImpl" />

</beans>




Spring2.0.8 450ミリ秒
Spring2.5.2 235ミリ秒

Spring2.0はDIのオーバーヘッドが2~3%ほどかかっていますが、Spring2.5ではそれほどかかっていないことがわかります。
でもまあ、DIのコストは気にする程度のものではないでしょう。



次は、scope="prototype"で。
100万回 * 100セットでは時間がかかりすぎたので、1万回 * 100セットで検証。


[applicationContext.xml]

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <bean id="parentBean" scope="prototype"
        class="springtest.bean.ParentBeanImpl">
        <property name="childBean">
            <ref bean="childBean" />
        </property>

    </bean>
    <bean id="childBean" scope="prototype"
        class="springtest.bean.ChildBeanImpl" />

</beans>



Spring2.0.8 122ミリ秒
Spring2.5.2 162ミリ秒

なんと、Prototypeではわずかですが2.5の方が遅いという結果に。




ところで、お客様に聞かれたのはSpring2.0と2.5の比較ですが、興味本位でSeasar2もほぼ同一プログラムで検証してみました。

結果は、Seasar圧倒的。これほどまでに差が出るとは・・・

Singleton、DIなし(ミリ秒)
100万回 * 100セット平均
Singleton、DIあり(ミリ秒)
100万回 * 100セット平均
Prototype、DIあり(ミリ秒)
1万回 * 100セット平均
Spring 2.0.8442450122
Spring 2.5.2234235162
Seasar 2.4.23848767



 ところで余談になりますが・・・

 最近Seasar界隈を中心に「スーツ or Geek論」が再燃していますが・・・
 ひがさんだって十分に「スーツなGeek」じゃない?と思うのは私だけでしょうか・・・

 大手SIerがSeasarをなかなか採用しない理由は、周辺プロダクトと開発環境のロックオンという理由も大きいと思います。私はSpringの方が柔軟性や他プロダクトとの親和性が高いと思います。

0 コメント:

Post a Comment