开发者

Java anonymous class efficiency implications

Is there any difference in efficiency (e.g. execution time, code size, etc.) between these two ways of doing things?

Below are contrived examples that create objects and do nothing, but my actual scenarios may be creating new Threads, Listeners, etc. Assume the following pieces of code happen in a loop so that it might make a difference.

Using anonymous objects:

void doSomething() {
    for (/* Assume some loop */) {
        final Object obj1, obj2; // some free variab开发者_开发知识库les

        IWorker anonymousWorker = new IWorker() {
            doWork() {
                // do things that refer to obj1 and obj2
            }
        };
    }
}

Defining a class first:

void doSomething() {
    for (/* Assume some loop */) {
        Object obj1, obj2;
        IWorker worker = new Worker(obj1, obj2);
    }
}

static class Worker implements IWorker {
    private Object obj1, obj2;
    public CustomObject(Object obj1, Object obj2) {/* blah blah */}

    @Override
    public void doWork() {}
};


The only practical difference between the anonymous classes and the top-level classes is that the anonymous classes will hold an implicit reference to the outer class.

This won't manifest itself in performance, but will impact you if you ever serialise these classes.


There should be little if any performance difference. If there is a difference it will be at a level where it is not worth worrying about.

IMO, you should focus on writing code that is readable and maintainable, and ignore "micro" performance issues until you have clear evidence that they are significant ... based on profiling the application.

(For the record, when an anonymous inner class refers to a final in an enclosing scope, this is implemented at the bytecode level by means of hidden constructor arguments and hidden instance attributes. The bytecodes will be almost the same as the bytecodes that you get from your other implementation.)


It's important to realize that anonymous classes are still classes that were known and fully-compiled at compile time. The fact that, say, you're defining an anonymous class body, perhaps with many methods and fields etc within a loop, doesn't mean that the runtime has to compile that type on every iteration.

Thus, any difference in performance between the two approaches are negligible. The important factors to consider are things like readability, reusability, testability, etc.


I actually HAVE noticed a significance performance hit when instantiating many instances of an anonymous class.

Thinking if might be due to the local class being static I removed that and it made no difference.

In my case, I was doing something 1000 choose 3 times which is 499,500. The version with the local class (regardless of static or not) took 26 seconds and the version with the anonymous functionally identical class took 2 minutes 20 seconds.


Regarding performance you should consider if an inner class should be created or not at all.

An example for bad practice is something like:

public List<String> someMethod() {
       return new ArrayList<String>() {{
                      add("Item one");
                      add("Item two");
              }};
}

While this syntactical convenience looks smart at a first glance, this (often unnoticed) creates an anonymous inner class whose object keeps a reference to the outer instance. As this object is also given to the outside as result value of someMethod, you cannot be sure what your caller does with this list. If he puts the resulting ArrayList instance into some static variable, your current Object will be kept forever too!


Speculating about code performance is an excellent way of wasting your time. Nothing compares to actually benchmarking the code. If you're worried about performance, measure the code. If you suspect that your code is sub-optimal, profile the code to figure out where the time is spent, then try to improve those parts. At this time it may be appropriate to actually study the byte code to see if that may give you a hint which implementation is more efficient.

When you've done that, measure the code again to make sure that you didn't make things worse, for example by making the code uglier and more difficult to maintain.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜