views:

44

answers:

2

Which of the following declaration would be the right one to choose for allocating the right amount of memory. Option 1 has an initial collection capacity of 0 and Option 2 has an initial capacity of 10 and Option 3 doesn't declare anything.

If the underlying ORM provider loads these object eventually, wouldn't it be using a setEmails(..) method to set the values of the Collection. If so, would it make sense to just declare this as in Option 3, so that I can avoid unnecessary memory allocation.

Option 1
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Email> emails = new HashSet<Email>(0);

or

Option 2
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Email> emails = new HashSet<Email>();

or

Option 3
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Email> emails;
+1  A: 

That's microoptimization.

Technically, in terms of memory allocation they are ordered:

Option 3 better than Option 1 slightly better than Option 2

But still, Option 2 might be your best choice

  • the Set won't have to be expanded when you add items
  • your code will be easier to handle, since you won't have to check for null
Bozho
@Bozho - If the underlying ORM uses setEmails(..) to set the emails on a lazy load, it's actually overriding my initial settings, so I thought Option 3 would be the most ideal since I will not be allocating any space. Your argument of the Set expanding automatically is not possible in this case
my app is getting slower and am trying to optimize where ever its possible
But when you create the object initially, you'd have to initialize it externally. A matter of taste. And this here is memory, not CPU (slowness) - look for problems elsewhere.
Bozho
Actually, an application that is *constantly* CGing might not perform very well. But 1. there is no proof that it's the case here and 2. not initializing some collections won't solve the problem.
Pascal Thivent
A: 

If so, would it make sense to just declare this as in Option 3, so that I can avoid unnecessary memory allocation.

Well, you do also create entities. And because I like to use defensive style programming methods when working with bi-directional associations, like this:

public void addToEmails(Email email) {
    emails.add(email);
    email.setUser(this);
}

I tend to prefer Option #2 because I don't have to do the null check.

And honestly, I don't even think about the "cost" of instantiating an empty collection. This is very likely not what will kill my application performances.

If your application is becoming slow (do you even know why it is? Is it really a memory or GC problem? what did you diagnose or measure?), I'm pretty sure that there are more critical optimizations than this one to do. Actually, I bet my shirt on it.

And don't forget:

If you cannot measure it, you cannot improve it. --Lord Kelvin

Pascal Thivent