こんどこそ。
サーバーはGlassfish V2で、クライアントは高精度カウンタで検証。
検証用コード
public class Main { static String[] urls = { "http://localhost:8080/SpringMVCTest/index.htm", "http://localhost:8080/StrutsTest/", "http://localhost:8080/JSFTest/", "http://localhost:8080/cubby-sample1.1.3/hello/", "http://localhost:8080/t2_samples05/hello", "http://localhost:8080/wicket-examples-1.4-rc1/helloworld/" }; static int count = 10000; public static void main(String[] args) { Client c = Client.create(); for(String url : urls){ double sum = 0; WebResource resource = c.resource(url ); for(int i=0;i<count;i++){ long start = System.nanoTime(); String result = resource.get(String.class); long end = System.nanoTime(); // System.out.println(result); double time = (end-start)/1000.0/1000.0; sum += time; // System.out.printf("%.2fms%n",time); } System.out.printf("★URL:%s%n平均%.2fms%n",url,sum/count); System.out.println("------------------------------"); } } }
結果。URL見ればどれがどれかはわかるはず。コードは基本的に変わっていないが、T2のサンプルはフォワードで出すようにしてある。Spring MVCはアノテーションによる設定に変えた。
今回はログが出るようなやつはすべてださないようにした。Cubbyはprint部分を消し、T2Frameworkはロギングのログレベルを大幅に下げた。コードは追ってないけどT2Frameworkは「ITDT0020」のログレベルが高すぎると思う。どのアクションクラスが呼ばれたかというのはトレースレベルにするべきかなと。
連続でテストするとメモリの状態やGC具合によって有利不利があらわれるかもしれないのでURLはそれぞれ単体でテストしてある。また、何度か計測して数値が低いやつを採用してある。T2やCubbyのようにログだしまくってる状態だと100マイクロ秒は遅くなってるようだ。
★URL:http://localhost:8080/SpringMVCTest/index.htm 平均1.09ms ------------------------------ ★URL:http://localhost:8080/StrutsTest/test.do 平均1.07ms ------------------------------ ★URL:http://localhost:8080/JSFTest/ 平均1.18ms ------------------------------ ★URL:http://localhost:8080/cubby-sample1.1.3/hello/ 平均1.35ms ------------------------------ ★URL:http://localhost:8080/t2_samples05/hello 平均1.21ms ------------------------------ ★URL:http://localhost:8080/wicket-examples-1.4-rc1/helloworld/ 平均3.53ms ------------------------------
Wicket遅すぎ。どうやらログを見るとサンプルが開発モードだったのが原因らしい。
というわけでdeployment modeにして動かす。バイナリいじるのは面倒だったのでシステムプロパティで。
結果
★URL:http://localhost:8080/wicket-examples-1.4-rc1/helloworld/ 平均2.88ms ------------------------------
うーん。確かに多少早くはなったけど、他のフレームワークの2〜2.5倍くらい遅いってのは場合によっては厄介かもしれない。
また、1万回のアクセスしたあと、Wicketだけは終了後にHDDがしばらく(10分弱くらい)アクセスしてる状態になる。もちろん実行中もアクセスランプが光りっぱなし。想像以上に他のフレームワークと負荷具合が違いすぎる感じ。なんか設定項目とかあるのかな。メモリが足りてないわけでもないのでセッション情報を独自にファイルに書き出してるというか、そんな感じかねぇ。アプリケーションサーバーを再起動させてもかわらなかったし。そもそもこのファイルはどこに書き出してるんだろうか。
あたりまえだけど、しばらくアクセスランプが光りっぱなしになってる間は大幅にサーバーの性能はダウンすることになる。ユーザーのアクセスが一段落したあとの集中してないときにもこのアクセスがはいってる状態になってるため結構つらい。レスポンスそのものの遅さよりこちらのほうがつらいなぁ。
おおむねこんな感じかな。
順位 | 重さ | フレームワーク |
---|---|---|
1 | とても軽い | Spring MVC 2.5, Struts 1.2 |
2 | 十分軽い | JSF 1.2, T2Framework 0.5 |
3 | 軽い | Cubby 1.1 |
4 | 普通 | なし |
5 | 重い | Wicket 1.4rc |
重いと軽いの間に存在しないのに普通を入れたのはここに大きな差があることを認識してもらうため。
JSFとWicketは他のアクションベースのフレームワークとは大幅に異なるから単純に比較は出来ないし、JSFはたぶんポストバックのときは重いのだろうなとか。複雑な画面になったときどうなるのかというのもあるが、それの検証は難しいと思うのでやめ。
1万回程度だと平均50〜100マイクロ秒くらいはぶれが出るので参考に。
他のフレームワークも試してみたいと思ったけど、ほかのはwarでサンプルコードが用意されてないのでやめた。手軽に試せるサンプルが用意されてるかどうかってのはやっぱり大きいと思う。