简体   繁体   English

计算HashMap / HashTable的调用次数

[英]Count number of invocations of HashMap/HashTable

I have a java progam in which there are a lot of HashMap/HashTable being used for mapping key-value pairs. 我有一个Java程序,其中有很多HashMap / HashTable用于映射键值对。 Now I want to profile or rather count how many times the get() and put() methods have been called in my program. 现在,我想分析或统计一下在程序中调用get()和put()方法的次数。

The approach which I was taking is that I extend the Java HashMap/HashTable classes and introduce a member called count and in the get() and the put() methods increment the count everytime the method gets invoked. 我采用的方法是扩展Java HashMap / HashTable类,并引入一个称为count的成员,并在get()和put()方法中每次调用该方法时增加计数。 This would involve a lot of refactoring as I would have to go and remove all the instantiations of the HashMap/HashTables to instead instantiate my extended class. 这将涉及很多重构,因为我将不得不删除HashMap / HashTables的所有实例化以实例化我的扩展类。 Is this approach reasonable or is there other better way of maintaining this count? 这种方法是否合理,或者还有其他更好的方法来保持这种计数?

The best solution for such a task is to use a Profiler such as YourKit or JProfiler . 此类任务的最佳解决方案是使用Profiler,例如YourKitJProfiler A profiler performs "instrumentation" on all (or a subset of) the classes loaded by the profiled JVM to perform exactly what you need: Count and measure all of the method invocations, without a single line of modified code. 探查器对由探查的JVM加载的所有类(或其子集)执行“工具” ,以准确执行您所需的操作:计算和测量所有方法调用,而无需一行修改的代码。

Both of the aforementioned profilers ship with trial licenses. 上述两个分析器都附带了试用许可证。 Once you have tried them, you'll probably buy one because they are very useful in so many situations. 一旦尝试过它们,您可能会购买一个,因为它们在很多情况下都非常有用。

You can use profiling tools which will tell you how many times a method is run and how long it takes for the code to be executed. 您可以使用性能分析工具,该工具将告诉您方法运行了多少次以及执行代码需要多长时间。 For example, you can do this in the Eclipse IDE: http://www.eclipse.org/projects/project.php?id=tptp.performance 例如,您可以在Eclipse IDE中执行此操作: http : //www.eclipse.org/projects/project.php?id=tptp.performance

One possible way, which is more a Hack I would not recommend for production but only for profiling. 一种可能的方式,更多是Hack,我不建议将其用于生产,而仅建议用于性能分析。 The idea would be to override the java.util.HashMap class. 这个想法是重写java.util.HashMap类。 Simply find the source code for that class, modify it with your profiling tools, then make sure it is on top of your classpath loading. 只需找到该类的源代码,使用分析工具对其进行修改,然后确保它位于类路径加载的顶部。

If profiling is what you need, you could use VisualVM as well to track all these calls. 如果需要进行分析,则还可以使用VisualVM来跟踪所有这些调用。

This article should help you understand why it is best to observe performance not too close to the bottleneck itself 本文应帮助您了解为什么最好观察性能不太接近瓶颈本身的情况

http://www.jinspired.com/site/case-study-scala-compiler-part-5 "Part of the problem here is that developers mistakenly believe that a performance measurement solution should direct them to the actual line of code that is the problem when generally the best starting point for both observation and tuning is just above the problem in the caller-callee chain providing an appropriate enclosing context to the execution." http://www.jinspired.com/site/case-study-scala-compiler-part-5 “这里的部分问题是,开发人员错误地认为性能测量解决方案应该将它们定向到实际的代码行,即通常情况下,观察和调整的最佳起点刚好在调用者-被调用者链中的问题之上,该问题为执行提供了适当的封闭上下文。

That said you can always count if need be but meter it back up the caller chain: 也就是说,您始终可以根据需要进行计数,但可以将其计入调用者链:

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

You may use inheritance : https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html 您可以使用继承: 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;
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM