开发者

JDK compiler optimize use of anonymous classes with no instance variables?

I was curious, I see this kind of thing a lot:

Arrays.sort(array, new Comparator<Integer>() {
    public int compare(Integer a, Integer b) {
        return Math.abs(a) < Math.abs(b);
    }
});

since the anonymous class created here has no instance variables, is the standard JDK compiler smart enough to only instantiate that anonymous class once and reuse it? Or is it advisable to instantiate that anonymous class in a static field开发者_开发知识库 and always pass the static Comparator object?

UPDATE: When I say "JDK compiler", I mean the JIT portion too. The above is also just an example. I was really curious if I should, as a best practice, create static fields for the above instead of inlining anonymous class instantiations. In some cases the performance/resource usage issue will be negligible. But other cases might not be...


javac will definitely not do such thing; that would violate the language semantics. JVM could optimize it in theory, but it's not that smart yet. A static one would be faster.

Ironically, such analysis and optimization would be easy for javac, and it can be done today, except it's forbidden to do so - the source says new, so javac must new.

Rumor has it that the coming lambda expression in java 8 will make an effort on this issue, in

Arrays.sort(array, (Integer a,Integer b) => Math.abs(a)<Math.abs(b) )

javac is required to analyze that the lambda is stateless, and a lazily created single instance is enough, and that's what it must compile the code into.


The answer is maybe.

javac will compile this into bytecode that is true to your code. Therefore, the class will be instantiate anew each time this code is called. However the JVM performs many sophisticated optimisations at runtime, and MIGHT - depending on many factors - perform some optimisations here.

In any case, unless you've noticed a real performance issue here, I'd recommend not trying to manually optimise.


You can use javap to check yourself; my suspicion is that it will create it on every call. Such optimizations are handled by hotspot but in this case since the anonymous only has methods (no fields to initialize) the overhead is very small.


The real question here is not what javac will do. As Steve McLeod says, javac will produce bytecode which matches your source code. The question is what hotspot will do at runtime. I imagine it will simple inline the whole lot (including the Math.abs() call).


The compiler does very little optimisation. The jit does most of it. It will optimise this code but it won't avoid creating Integer objects and unless you have an array of Integer this will be your bottle neck. So much so that any other optimisation it does won't matter.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜