簡體   English   中英

ConcurrentHashMap.putIfAbsent的性能

[英]Performance of ConcurrentHashMap.putIfAbsent

他的講有效的Java在54:15約書亞布洛赫建議使用get之前putIfAbsent ,以提高性能和並發性。 這引出了一個問題,為什么這個優化已經沒有像

public V BETTER_putIfAbsent(K key, V value) {
    V result = get(key);
    if (result!=null) return result;
    return ORIGINAL_putIfAbsent(key, value);
}

我猜這是因為性能取決於使用模式。 對於大多數putIfAbsent調用將成功的地圖,然后使用get來保護它將會更慢。 對於putIfAbsent經常會失敗的地圖,然后用get來保護它會更快。

通過不對常見故障情況進行優化,您可以自由選擇哪種方法對您的地圖更快。

在視頻的示例中,putIfAbsent通常會失敗,因此使用get來保護它會更快。

這增加了雙重檢查鎖定,事務語義保持不變; 所以沒有錯

它是否實際上是一種優化取決於使用情況。 我們總是試圖檢查我們知道存在更便宜的解決方案的特殊情況

if A
    cheapSolutionForA();
else
    genericSolution();

這可能有用,或者沒有 - 如果A很少是true ,額外的檢查費用比它節省的多。 (當A確實有時真的,它可以破壞CPU分支預測,即使A = true,總是使用通用解決方案可能更便宜)

在約書亞的例子中, A確實經常是真的。 他必須多次請求相同字符串的實習字符串(值相同,而不是同一性),因此在大多數調用中,地圖已經有了密鑰。

如果對intern()每次調用都得到一個不同的字符串,那么地圖永遠不會有密鑰,並且他的優化會發生逆火 - “優化”會花費更多時間,並且不會保存。

當然,在字符串實習生方面,第一種情況在實踐中更為現實。

一般來說, putIfAbsent()無法預測它的使用方式,因此在其中包含這種特殊情況“優化”是不明智的。 在許多用例中,爭用率很低,當putIfAbsent時,映射很可能沒有密鑰,如果內置“優化”,則在這些情況下會出錯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM