Nicole
Nicole

Reputation: 33227

Are getters bad for performance in Java?

Given the following two code options, is there any performance benefit (over a very large scale or a long period of time) of the second over the first?

Option 1

private Map<Long, Animal> animals = ...;
public Map<Long, Animal> getAnimals() {
    return animals;
}

public void useAnimals() {
    for (int i=0; i < SOME_LARGE_NUMBER; i++) {
        Animal animal = getAnimals().get(id);
    }
    // Many many calls to getAnimals() are made...
}

Option 2 - no getter

private Map<Long, Animal> animals = ...;

public void useAnimals() {
    for (int i=0; i < SOME_NUMBER; i++) {
        Animal animal = animals.get(id);
    }
    // No method calls made
}

If it is bad for performance, why, and how should I determine whether it is worth mitigating?

And, would storing the result of getAnimals() as a local provide a benefit...


Note: I previously said "encapsulation". I changed it to "getter" because the purpose is actually not that the field can't be modified but that it can't be reassigned. The encapsulation is simply to remove responsibility for assignment from subclasses.

Upvotes: 0

Views: 931

Answers (4)

JB Nizet
JB Nizet

Reputation: 692191

The second snippet is more encapsulated than the first one. The first one gives access to the internal map to anyone, whereas the second keeps it encapsulated in the class.

Both will lead to comparable performance.

EDIT: since you change the question, I'll also change the answer.

If you go through a getter, and the getter is not final, it means that subclasses may return another map than the one you hold in the class. Choose whether you want your method to operate on the subclass's map or on the class's map. Both could be acceptable, depending on the context.

Anyway, suppose your subclass always makes a defensive copy of the map, you'll end up having many copies if you don't cache the result of the getter in a local variable of useAnimals. It might be required to always work on the latest value of the subclass's map, but I doubt it's the case.

If there is no subclass, or the subclass doesn't override the method, or override it by always returning the same map, both will lead to comparable performance and you shouldn't care about it.

Upvotes: 5

andrershov
andrershov

Reputation: 468

Well, I don't think that JVM will inline the function call. So probably it may affect performance. The better way is to create local variable and assign class field animals to it.

Upvotes: -3

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340993

Most likely JVM will inline getAnimals() invocation in tight loop effectively falling back to Option 1. So don't bother, this is really a micro (nano?) optimization.

Another thing is migrating from field access to local variable. This sounds good since instead of traversing through this reference every time you always have a reference on the stack (two memory accesses vs. one). However I believe (correct me if I'm wrong) that since animals is private and non-volatile again JVM will perform this optimization for you at runtime.

Upvotes: 8

user177800
user177800

Reputation:

Have you profiled this to see if it matter, for a modern JIT I would guess it would get optomized away, especially if animals was marked final but there is nothing stopping you from testing this yourself.

Either way, I am 100% this would NEVER be your bottle neck in an application.

Upvotes: 3

Related Questions