Why is list.size()>0 slower than list.isEmpty() in Java?

后端 未结 9 1893
误落风尘
误落风尘 2020-12-13 03:58

Why is list.size()>0 slower than list.isEmpty() in Java? On other words why isEmpty() is preferable over size()>0?<

相关标签:
9条回答
  • 2020-12-13 04:05

    For ArrayList, yes — you are correct that the operations take (roughly) the same time.

    For other implementations of List — for example, a naïve linked list* — counting the size might take a very long time, while you only actually care whether it is greater than zero.

    So if you absolutely know that the list is an implementation of ArrayList and will never ever change, then it does not really matter; but:

    1. This is bad programming practice to tie yourself down to a specific implementation.
    2. If things change a few years down the line with code restructuring, testing will show that "it works," but things are running less efficiently than before.
    3. Even in the best case, size() == 0 is still not faster than isEmpty(), so there is no compelling reason to ever use the former.
    4. isEmpty() is a clearer definition of what it is you actually care about and are testing, and so makes your code a bit more easily understandable.

    * I originally wrote LinkedList here, implicitly referencing java.util.LinkedList, though that particular implementation does store its size explicitly, making size() an O(1) operation here. A naïve linked list operation might not do this, and in the more general sense there is no efficiency guarantee on implementations of List.

    0 讨论(0)
  • 2020-12-13 04:07

    Your testing code is flawed.

    Just reverse the order, i.e call isEmpty first and size > 0 second and you'll get the opposite result. This is due to class loading, caching, etc.

    0 讨论(0)
  • 2020-12-13 04:08

    It is impossible to say in general which is faster, because it depends on which implementation of interface List you are using.

    Suppose we're talking about ArrayList. Lookup the source code of ArrayList, you can find it in the file src.zip in your JDK installation directory. The source code of the methods isEmpty and size looks as follows (Sun JDK 1.6 update 16 for Windows):

    public boolean isEmpty() {
        return size == 0;
    }
    
    public int size() {
        return size;
    }
    

    You can easily see that both expressions isEmpty() and size() == 0 will come down to exactly the same statements, so one is certainly not faster than the other.

    If you're interested in how it works for other implementations of interface List, look up the source code yourself and find out.

    0 讨论(0)
  • 2020-12-13 04:09

    According to PMD ( static ruleset based Java source code analyzer ) isEmpty() is preferred. You can find the PMD ruleset here. Search for "UseCollectionIsEmpty" rule.

    http://pmd.sourceforge.net/rules/design.html

    According to me it also helps in keeping the entire source code consistent rather than half of the folks using isEmpty() and the rest using size()==0.

    0 讨论(0)
  • 2020-12-13 04:20

    I'm sorry, but your benchmark is flawed. Take a look at Java theory and practice: Anatomy of a flawed microbenchmark for a general description on how to approach benchmarks.


    Update: for a proper benchmark you should look into Japex.

    0 讨论(0)
  • 2020-12-13 04:23

    Given those two implementations, the speed should be the same, that much is true.

    But those are by far not the only possible implementations for these methods. A primitive linked list (one that doesn't store the size separately) for example could answer isEmpty() much faster than a size() call.

    More importantly: isEmpty() describes your intent exactly, while size()==0 is unnecessarily complex (not hugely complex of course, but any unnecessary complexity at all should be avoided).

    0 讨论(0)
提交回复
热议问题