次の特性を持つメモ化キャッシュを作成しています。
- キャッシュミスは、エントリの計算と保存につながります
- この計算は非常に高価です
- この計算はべき等です
- 制限なし(エントリは削除されません)以降:
- 入力は最大500エントリになります
- 保存された各エントリは非常に小さい
- キャッシュは比較的短命です(通常は1時間未満)
- 全体として、メモリ使用量は問題ではありません
- 何千もの読み取りがあります-キャッシュの存続期間にわたって、99.9%以上のキャッシュヒットが予想されます
- スレッドセーフである必要があります
何が優れたパフォーマンスを発揮するのでしょうか、またはどのような条件下で一方のソリューションが他方よりも優先されるのでしょうか。
ThreadLocal HashMap:
class MyCache {
private static class LocalMyCache {
final Map<K,V> map = new HashMap<K,V>();
V get(K key) {
V val = map.get(key);
if (val == null) {
val = computeVal(key);
map.put(key, val);
}
return val;
}
}
private final ThreadLocal<LocalMyCache> localCaches = new ThreadLocal<LocalMyCache>() {
protected LocalMyCache initialValue() {
return new LocalMyCache();
}
};
public V get(K key) {
return localCaches.get().get(key);
}
}
ConcurrentHashMap:
class MyCache {
private final ConcurrentHashMap<K,V> map = new ConcurrentHashMap<K,V>();
public V get(K key) {
V val = map.get(key);
if (val == null) {
val = computeVal(key);
map.put(key, val);
}
return val;
}
}
スレッドごとのすべてのキャッシュミスのためにスレッドが多い場合、ThreadLocalソリューションは最初は遅くなると思いますが、数千回の読み取りを超えると、償却コストはConcurrentHashMapソリューションよりも低くなります。私の直感は正しいですか?
または、さらに良い解決策はありますか?