2012-08-29 23 views
2

我有一個java程序,其中有很多HashMap/HashTable用於映射鍵值對。現在我想描述一下get()和put()方法在程序中被調用了多少次。計數HashMap/HashTable的調用次數

我採用的方法是擴展Java HashMap/HashTable類,並引入一個名爲count的成員,並在get()方法和put()方法每次調用方法時遞增計數。這將涉及到很多重構,因爲我必須去除所有HashMap/HashTables的實例化,而不是實例化我的擴展類。這種方法合理嗎?還是有其他更好的方法來維持這個數量?

+0

我想你可以使用反射和插入掛鉤的方法做到這一點。最初的谷歌搜索表明,至少有可能。 – bdares

+0

上帝保佑你搜索並取代所有! :P – Averroes

+0

@bdares您能否詳細說明如何完成這個反射方面(我瞭解Reflection)。 – user1420750

回答

1

此類任務的最佳解決方案是使用Profiler,如YourKitJProfiler。概要分析器對概要分析的JVM加載的類的所有(或其子集)執行"instrumentation",以準確執行您所需的操作:計算並測量所有方法調用,而不需要一行修改代碼。

上述兩個分析器均附帶試用許可證。一旦你嘗試過它們,你可能會購買一個,因爲它們在很多情況下非常有用。

+1

+1這是最好的方法。如果這不是一個選項,您可以修改HashMap或Hashtable用於測試目的。 –

+0

@PeterLawrey我同意這是最好的方法,但不是現在的選擇。我想我會繼續並修改HashMap | HashTable並繼續我正在做的事情。 – user1420750

+0

要修改你需要預先掛起到您的引導類路徑或他們在'的lib/endorsed'目錄 –

0

一種可能的方式,這更多的是我不推薦用於生產的Hack,但僅用於分析。這個想法是重寫java.util.HashMap類。只需找到該類的源代碼,使用分析工具對其進行修改,然後確保它位於類路徑加載之上。

如果分析是你需要的,你也可以使用VisualVM來跟蹤所有這些調用。

0

本文將幫助你理解爲什麼它是最好的觀察效果不是太接近瓶頸本身

http://www.jinspired.com/site/case-study-scala-compiler-part-5 「這裏的問題的部分原因是開發商錯誤地認爲績效測量解決方案應該引導他們到當通常觀察和調優的最佳起點位於調用者 - 被調用鏈中的問題的上方,爲執行提供適當的封閉上下文時,實際上是問題的代碼行就是問題。「

這就是說,你總是可以指望如果需要的話,但米回來了主叫鏈:

http://www.jinspired.com/site/case-study-scalas-compiler-part-1 http://www.jinspired.com/site/case-study-scala-compiler-part- 2

-1

您可以使用繼承:https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

public class Main{ 
    public static void main(String[] args){ 
      HashMap<Integer,Integer> mymap = new myMap<Integer,Integer>(); 
      mymap.put(3,4); 
      mymap.put(5,6); 
      System.out.println(mymap.get(3));//this will print 4; 
      System.out.println(mymap.getCountGets());//this will print 1 
      System.out.println(mymap.getCountPuts());//this will print 2 
    } 
} 
class myMap<K,V> extends HashMap<K,V> { 

public myMap(){ 
    countPuts = 0; 
    countGets = 0; 
} 
private int countPuts, countGets ; 

@Override 
public V put(K k, V v){ 
    countPuts++; 
    return super.put(k, v); 
} 
@Override 
public V get(Object k){ 
    countGets++; 
    return super.get(k); 
} 

public int getCountGets(){ 
    return countGets; 
} 

public int getCountPuts(){ 
    return countPuts; 
} 

}

+0

你需要解釋你的答案添加到罐子原來的。 – vjdhama

+0

繼承是一個面向對象的概念,使利用超類的行爲,不僅如此,但修改它也(覆蓋)。 –