Question

I have some classes that have ArrayList fields that are only sometimes used. I generally initialize these fields like so:

private List<Widget> widgets = new ArrayList<>();

I understand about using the overload constructors to set the initial capacity, so I'm wondering if I should declare these fields as such:

private List<Widget> widgets = new ArrayList<>(0);

The dilemma, is that if I initialize the list with 0 then the list will always have to re-initialize itself for adding even one item. But, if I use the default constructor, which gives a default capacity of 10, then I may have a bunch of items (and there can be many) that are wasting memory with unused capacity.

I know some of you are going to push back asking 'how often' and 'how many items are you expecting' but I'm really looking for the "best practices" approach. All things being ~equal, should one initialize with (0) or () on a list that is sometimes used?

It's our department policy to always initialize lists, so I may not simply leave the lists as null, besides, that would just side-step the question.

Was it helpful?

Solution

Premature optimisation is the root of all evil. - D. Knuth.

This seems like the kind of "performance issue" which actually never has any effect on performance. For one thing, how sure are you that these empty lists are actually initialised? I suspect that most modern compilers delay initialisation of objects until they know for sure that there will be a call on them. So if you pass the no arg constructor it will most likely never be used unless something is added to the list. On the other hand, if you use the 0 argument constructor, it guarantees that it has to resize every one that it uses.

These are the three laws of performance optimisation

  1. Never assume that you know what the compiled code is actually doing, or that you can sport small optimisations better than the compiler can.
  2. Never optimise without using a profiler to work out where the bottleneck is. If you think that you know, refer to rule number (1).
  3. Don't bother unless your application has a performance issue. Then refer to rule (2).

On the off chance that you somehow still believe that you understand compilers, check out this question: Why is it faster to process a sorted array than an unsorted array?

OTHER TIPS

If the list is not always used use lazy initialization

private List<Widget> widgets;

private List<Widget> getList() {
    if (widgets == null) {
         widgets = new ArrayList<>();
    }
    return widgets;
}

If you set it to 0 the ArrayList will have to resize anyhow, so really you're shooting yourself in the foot. The only time you would benefit from an explicit declaration of size would be if you already know the maximum bounds that you will be reaching in your list.

As stated, this is a micro-optimization, it's more likely you will find other things that you can significantly improve than the initial size of your ArrayList.

I tent to disagree that these optimisation are bad. If you declare an arraylist that holds n elements (8-th by default if Im not mistaken), and you put one more, then arraylist, internally will double the size it holds. When you remove this element later, the list will not decrease.

ArrayList utilizes processor cache a lot and actually is so fast, that you don't need to optimize it any furter. Still, if you have to create millions of tiny ArrayList instances it may worth thinking of reworking your overall design and not bother about default AL capacity.

As has already been said, Lazy initialization can help you by postponing the moment when you have to initialize the list (and therefore choose its initial size).

If Lazy initialization is not possible because of your department policy that does not allow to initialize with null an object (for which I do not find much sense), a workaround might be to initialize an empty list as

List widget = new ArrayList<>(0)

and only when (and if) you actually need to work with the list, you create a new list object:

widget = new ArrayList<>(someSize)

and hopefully at that moment you could know the max size that the list can reach (or at least its order of magnitude).

I know, this is a very stupid trick, but it adhers to your policy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top