結論
java.text.SimpleDateFormat の使用にはいくつかの注意が必要である。
-
SimpleDateFormatはスレッド・セーフではない。複数のスレッドで同時に使用してはならない。 -
SimpleDateFormatはシリアライズ可能であるが、シリアライズすべきではない。 - 利用ケースによるが、おそらくほとんどのケースにおいて
SimpleDateFormatを毎回生成せず、static で一度だけ生成し、同期を取りながら使用したほうが高速である。
SimpleDateFormat はシリアライズできてしまうが...
SimpleDateFormat の親クラスが java.io.Serializable を実装しているため、シリアライズできてしまう。しかし、シリアライズしてみると、出力データサイズが 37 kB とかなり大きなサイズになってしまう。
テストプログラム これは、
SimpleDateFormat の中で java.text.DateFormatSymbols インスタンスを保持している。このクラスは月、曜日、タイムゾーンデータなど、地域対応が可能な日付/時刻フォーマットデータを保持しているため、かなり大きなデータ量となる。自分で明示的に
SimpleDateFormat に格納しているならともかく、通常のケースでこれをシリアライズする必要はない。オブジェクト生成コスト vs 同期コスト
次の2つのプログラムを考えてみる。どちらが高速に動作するだろうか?code-1: 実行のたびに SimpleDateFormat オブジェクトを生成して利用するケース。実行するたびに オブジェクト生成コストがかかっている。
code-2: static で一度だけ SimpleDateFormat オブジェクトを生成するケース利用する際に synchronized で同期をとって利用する。
同期コストがかかっている。
性能測定結果
いずれのケースでも code-2 の方が高速に動作した。なお、テストで利用したマシンは CPU が Core2duo であるため、2 スレッドで実行できる分、複数スレッドで実行した場合、 code-1 は高速化している。
| スレッド数 | code-1 | code-2 | ||
|---|---|---|---|---|
| プログラム | 実行時間 [msec] |
プログラム | 実行時間 [msec] |
|
| 1 | Test1_1 | 5656 | Test2_1 | 796 |
| 10 | Test1_2 | 3359 | Test2_2 | 937 |
| 100 | Test1_3 | 3625 | Test2_3 | 1204 |
static に生成して利用するのはガベージ・コレクションの観点からも優位である。
SimpleDateFormat オブジェクトを毎回生成するということは、生存時間の短いオブジェクトをより多く発生することになり、GC 頻度を高めることになる。
コメントする