前回は、限定された要件を満たす最低限のシンプルな実装を作成してみました。今回は、OSCache と EhCache とのベンチマークをしてみます。
自作キャッシュは、とりあえず OfCache という名前にしておきます。
環境
・おいらのノートPC
・シングルCPU、シングルコア
設定
EhCache
<ehcache>
<defaultCache
maxElementsInMemory="10000000"
eternal="true"
overflowToDisk="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
diskPersistent="false"
memoryStoreEvictionPolicy="LRU"
/>
<cache
name="simpleGetTest"
maxElementsInMemory="10000000"
eternal="true"
overflowToDisk="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
diskPersistent="false"
memoryStoreEvictionPolicy="LRU"
/>
<cache
name="concurrentGetTestWithNoEntryLevelConcurrency"
maxElementsInMemory="10000000"
eternal="true"
overflowToDisk="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
diskPersistent="false"
memoryStoreEvictionPolicy="LRU"
/>
<cache
name="concurrentRandomGetTest"
maxElementsInMemory="10000000"
eternal="true"
overflowToDisk="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
diskPersistent="false"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
OSCache
cache.memory=true
cache.capacity=-1
cache.algorithm=com.opensymphony.oscache.base.algorithm.UnlimitedCache
cache.blocking=false
ベンチマーキング
メモリ消費量(100万件put。key=Integer, value=new Object())
キャッシュ種別 |
使用メモリ |
EhCache |
143,658,232 Bytes |
OSCache |
327,277,872 Bytes |
OfCache |
56,386,816 Bytes |
- EhCacheは、今回のユーザー要件に必要ない多くのメタ情報をエントリに持たせるため、メモリを浪費していると考えられます。メタ情報が必要ない要件にはそれに応じた実装が使えるといいのですが。
- OSCacheは、キーをStringに変換して持つ仕様であることが、オンメモリキャッシュとして致命的なメモリの浪費を引き起こしています。
- OfCacheは、シンプルなキャッシュなので、必要最低限のメモリしか消費していません。
get100万回
EhCache |
OSCache |
OfCache |
938 ms |
2,469 ms |
688 ms |
- EhCache と OfCache の速度はそれほど変わりません。OfCache にも統計情報その他の処理を追加すると、差は縮まると考えられます。
- OSCacheは、かなり遅いです。キーを文字列にしていることが大きく影響していそうです。
get100万回、10スレッド並行、並行アクセスされるエントリなし
EhCache |
OSCache |
OfCache |
11,328 ms |
64,657 ms |
3,844 ms |
- OfCache はダントツに速いです。EhCache は、getメソッドそのものをsynchronizedにしているため、複数スレッドの同時アクセスができないというのが大きな理由でしょう。
- OSCache はダントツに遅いです。OfCacheの15倍以上遅いです。
get100万回、10スレッド並行、keyは100種類でランダムアクセス
EhCache |
OSCache |
OfCache |
12,235 ms |
18,110 ms |
2,719 ms |
- ここでも OfCache はダントツに速いです。OfCache は、同一エントリへのgetでも並行アクセスが可能なので高速です。
- OSCache は、キーの種類が少ないほうが高速に動作するようです。(ソースは追ってませんので確証はありませんが)
get/put100万回、10スレッド並行、keyは100種類でランダムアクセス
EhCache |
OSCache |
OfCache |
11,766 ms |
33,610 ms |
3,329 ms |
- ここでも OfCache はダントツに速いです。OfCache は、put時もある程度の並行アクセスが可能なので、put が混ざっても大きな性能低下がありません。
- EhCache は、getもputも並行動作ができないので、putが混在しても性能に変化はありません。
- OSCache は、ダントツに遅いです。OfCacheの10倍以上遅いです。ヒープは1GBあるし、使用メモリを監視して、容量の限界に近づいたことによるGCの頻発でないことは確認しました。ここまで差があると、実験方法自体を疑ってかかりたくなりますが、、、。