我有一个java程序,其中有很多HashMap / HashTable用于映射键值对。现在我想要分析或者更确切地计算在我的程序中调用了get()和put()方法的次数。
我采用的方法是扩展Java HashMap / HashTable类并引入一个名为count的成员,并在get()和put()方法中每次调用该方法时都会增加计数。这将涉及大量的重构,因为我必须去除HashMap / HashTables的所有实例化而不是实例化我的扩展类。这种方法是否合理,还是有其他更好的方法来维持这种计数吗?
答案 0 :(得分:1)
此类任务的最佳解决方案是使用YourKit或JProfiler等Profiler。探查器对配置的JVM加载的类的所有(或子集)执行"instrumentation",以完全满足您的需要:计算并测量所有方法调用,而无需单行修改代码。
上述两个分析器都附带试用许可证。一旦你尝试过它们,你可能会买一个,因为它们在很多情况下非常有用。
答案 1 :(得分:0)
您可以使用分析工具来告诉您运行方法的次数以及执行代码所需的时间。例如,您可以在Eclipse IDE中执行此操作:http://www.eclipse.org/projects/project.php?id=tptp.performance
答案 2 :(得分:0)
一种可能的方式,更多的是黑客,我不建议用于制作但仅用于剖析。我们的想法是覆盖java.util.HashMap类。只需找到该类的源代码,使用性能分析工具对其进行修改,然后确保它位于类路径加载之上。
如果您需要进行性能分析,也可以使用VisualVM来跟踪所有这些来电。
答案 3 :(得分:0)
本文应该帮助您理解为什么最好观察性能并不太接近瓶颈本身
http://www.jinspired.com/site/case-study-scala-compiler-part-5 “这里的部分问题是,开发人员错误地认为性能测量解决方案应该将它们引导到实际的代码行,而这通常是观察和调优的最佳起点就在呼叫者 - 被调用者的问题之上。 chain为执行提供了适当的封闭上下文。“
这就是说,如果需要的话,你可以随时计算,但可以将其计入呼叫链:
http://www.jinspired.com/site/case-study-scalas-compiler-part-1 http://www.jinspired.com/site/case-study-scala-compiler-part-2
答案 4 :(得分:-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;
}
}