Why is Arrays.fill() not used in HashMap.clear() anymore?

后端 未结 5 547
太阳男子
太阳男子 2021-01-30 16:02

I noticed something strange in the implementation of HashMap.clear(). This is how it looked in OpenJDK 7u40:

public void clear() {
    modCount++;
          


        
5条回答
  •  独厮守ぢ
    2021-01-30 16:20

    For me, the reason is a likely performance inprovement, at a negligible cost in terms of code clarity.

    Note that the implementation of the fill method is trivial, a simple for-loop setting each array element to null. So, replacing a call to it with the actual implementation does not cause any significant degradation in the clarity/conciseness of the caller method.

    The potential performance benefits are not so insignificant, if you consider everything that is involved:

    1. There will be no need for the JVM to resolve the Arrays class, plus loading and initializing it if needed. This is a non-trivial process where the JVM performs several steps. Firstly, it checks the class loader to see if the class is already loaded, and this happens every time a method is called; there are optimizations involved here, of course, but it still takes some effort. If the class is not loaded, the JVM will need to go through the expensive process of loading it, verifying the bytecode, resolving other necessary dependencies, and finally performing static initialization of the class (which can be arbitrarily expensive). Given that HashMap is such a core class, and that Arrays is such a huge class (3600+ lines), avoiding these costs may add up to noticeable savings.

    2. Since there is no Arrays.fill(...) method call, the JVM won't have to decide whether/when to inline the method into the caller's body. Since HashMap#clear() tends to get called a lot, the JVM will eventually perform the inlining, which requires JIT recompilation of the clear method. With no method calls, clear will always run at top-speed (once initially JITed).

    Another benefit of no longer calling methods in Arrays is that it simplifies the dependency graph inside the java.util package, since one dependency is removed.

提交回复
热议问题