2

How is the performance/reliability picture for the following cases:

public class A {
    private SomeObject a = new SomeObject();

    //...

    public void method() {
        a.callSomeMethod();
    }

    //...
}

versus:

public class A {
    //...

    public void method() {
        SomeObject a = new SomeObject();
        a.callSomeMethod();
    }

    //...
}

I get it, from the testability point of view, the second choice is not that good. But how about performance, reliability - on which path should you go? To init the object as a filed and use it heavily or init it every time you need it?

Later edit: the construction of the object does not take long. The method is heavily used.

1
  • 2
    Functionally those two do different things. In the first case a is initialized once, in the second case it is recreated every time the method is invoked. So comparing performance seems a bit useless. Additionally for the second sample, it might as well be a static function. Commented Nov 5, 2013 at 12:17

7 Answers 7

2

Performance issue isn't the biggest issue here.

Speaking about performance only, it depends on your use.

The first version can be better as you don't create new SomeObject every method call.

The second one is better if you create a lot of As and only call method few times. (As @Marko Topolnik suggested)

However, the biggest issue here is correctness. Using the same object in every call for method is different than using new SomeObject every call.

This issue is much more important than performance.

Sign up to request clarification or add additional context in comments.

4 Comments

You can't decide which has better performance until you know how many objects are created vs. how many times method is called on them. Either can be better.
@Marko Topolnik how can the second option be better performance-wise?
This way: for (int i = 0; i < 1_000_000_000; i++) new A();
that's what lazy initialization is for. :)
1

It depends.

Performance

If you want to evaluate performance differences between two abstract options as you have here; the best way is to exaggerate the scale of everything. For example, assume that SomeObject takes an inordinate amount of time to instantiate (say, 600 seconds), and that you're planning on calling method() a lot (because performance issues are often not realized until projects scale).

Well it's obvious: option 1 will "perform" better over multiple method() calls, since option 2 results in a gigantic operation each time you want to call method. (Yes, as a rough performance test you can run each option through a for loop and compare the elapsed time, but it should be easy to see: all else being the same, creating an object n times is going to take more time than creating an object once).

But performance in itself in the exaggerated example is not necessarily a reason to favor option 1 in all cases.

Architecture

Option 2

It really comes down to the architecture of SomeObject. What is SomeObject? It could be that SomeObject is an object you cannot keep open for the lifetime of A; for example, it could be some kind of stream reader that locks down a resource while it is reading from the stream. In this case you might not want to have SomeObject "open" all the time blocking that resource; it should be disposed at the end of the method() call.

Option 1

Well, but perhaps SomeObject is something like a Service or Facade that exposes business logic. As you alluded to in your question it is "better for testing", and the full answer to that is, yes, it gives an easier hook for dependency injection, which is a key component to unit testing. (Although, typically it would be rewritten as private SomeObject a;, with a constructor like public a (SomeObject a) { this.a = a; } to follow the dependency injection / inversion of control paradigm. However, the end result is the same for the purpose of this question.)

In the case of a (well-designed) Service or utility function, you'd expect that it would handle object disposal itself (privately). The more utilized pattern in this case would be option 1, since it gives you one place to manage the dependency instead of within every method that uses it.

Your choice

Knowing the above should be enough to make an informed decision.

  • Option 1 - Services, Facades, utilities, etc.
  • Option 2 - Objects needing to be disposed; objects that implement Closable, like StreamReader, FileWriter, etc.

Comments

1

How is the performance/reliability picture for the following cases

They're totally different, in the first case a is a class member, in the second a is known only in the scope of method. I'm not sure how much good is "comparing" the performance of these two codes.

But it's good to note that the in the first code someObject is not created on each call of method. I don't know how many times you are calling method, your question is hard to answer in it's current revision.

Comments

1

Actually here can be some real performance issues in second case if your SomeObject constructor body contains code which execution can take a long time, because in second case You are constructing SomeObject object every time when A.method() is being called.

Comments

1

Yes. There will be a hit on performance. In the first scenario SomeObject's object is not created everytime you enter method(). In the second case, each time you enter method(), a new SomeObject is created which is not preferable usually. But on the other hand, one must also look at the scope of the object and garbage collection mechanism. In the second scenario, as soon as the method call returns/ends, the scope of the created object is also lost. So, it will be available for the garbage collector. So,IF MEMORY IS AN ISSUE, then you might want to go for the second option. i.e, if there are several hundred objects to be created, then you might want to consider the second option. And the disadvantage of option 1 is all the composed objects will persist as long as the parent object - instance of class A exists.If you keep on doing

public class A {
    private SomeObject a1 = new SomeObject();
    private SomeObject a2 = new SomeObject();

    private SomeObject a1000 = new SomeObject();
    //...

    public void method() {
        a.callSomeMethod();
    }

//...

}

The above code is less efficient than using a for loop and calling method() 1000 times and creating an object each time method() is called.

But then again, its a design issue. Based on your needs one option is better than the other. Kindly correct me if i am wrong.

Comments

1

It's been covered by other answers so I won't repeat too much. It really depends on the use and structure of both A and SomeObject. And depending on the situation, there are other options. If object creation is an issue with SomeObject AND the number of calls to method are relatively in infrequent, it may make sense to use lazy initialization:

public class A{
   private SomeObject o;

   public void method(){
       if(o == null){
            o = new SomeObject();
       }
       o.callSomeMethod();
   }
}

Also, marking references as final may help with performance (at least it used to):

public class A{
       private final SomeObject = new SomeObject();
       ....
}

Comments

0

The Main difference is the scope of the variable. In the first it is an instance variable and later it is a local variable.

If the Object is going to be used only inside a that method and is going to change on each invocation, then you may go for second approach

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.