2005年4月30日
Javaの高速化
Javaで高速に動くコードを書こうと思った場合、一番効くのが new を少なくすることだ。new はオブジェクトを「出産」するぐらい大変だと思ったほうがいい。
ループの中で、不要な new をするのは無駄である。できるだけループの外で作っておき、ループの中では再利用しまくる。
サーブレットの場合、必要なオブジェクトは init() で作成しまくっておくのが良い。サーブレットがCGIに勝る点は「常駐していること」である。事前に出来る処理は init() で行うことでサーブレットのメリットが生かされる。
doGet() などは、引数にレスポンスオブジェクトが入っている。なぜ、返り値ではなく、引数なのか。返り値だと、doGet() の中で new しなければならない。引数なら、サーブレットエンジンにて new しておくことが出来る。おそらく、サーブレットエンジンは最大同時接続数分のレスポンスオブジェクトを生成済みで、リクエスト毎に new はせず生成済みオブジェクトを渡すだけにして、高速化しているものと思われる。
リクエスト毎にSimpleDateFormat を「出産」して、日付を加工して表示しているコードを見るとムカつく。あーもー、こーゆーのはあらかじめ作っとけよ! と思う。
とにかく、そうやってinit()を膨らましていく。最近はサーブレットエンジン自身も起動時の処理が増えているように思う。起動にやたら時間がかかり、メモリを食い、しかし、1リクエストあたりの時間は短い。
こうやって、init()を膨らますと、オブジェクト指向から離れていく。高速化とオブジェクト指向的美しさは相反する。速くて美しいコードは難しい。
このエントリーのトラックバックURL:
http://weblog.rukihena.com/mt/mt-tb.cgi/64
> リクエスト毎にSimpleDateFormat を「出産」して、
> 日付を加工して表示しているコードを見るとムカつく。
> あーもー、こーゆーのはあらかじめ作っとけよ! と思う。
同意です。
ただ、SimpleDateFormatの場合はスレッドセーフでは無いですので、
new しないのであれば、適切に同期化する処理(synchronized)を入れておかないといけませんよね。
釈迦に説法かと思いますが。