0

I have created an Integer list containing 10 numbers in java.I would like to get the sum of the numbers in the list.For that I have used four methods to iterate through the list and return the sum.The code for the same is given below.

public static void main(String[] args) {

    List<Integer> numbers=Arrays.asList(1,5,10,25,30,17,3,9,11,26);

    //Using simple for loop for finding sum of numbers in the list
    System.out.println(sumOfNumbersUsingSimpleForLoop(numbers));

    //Using listIterator interface for finding sum of numbers in the list
    System.out.println(sumOfNumbersUsingIterableInterface(numbers));

    //Using enhanced for loop for finding sum of numbers in the list
    System.out.println(sumOfNumbersUsingEnhancedForLoop(numbers));

    //Using lambda expression for finding sum of numbers in the list
    System.out.println(sumOfNumbersUsingLambdaExpression(numbers));



}
public static int sumOfNumbersUsingSimpleForLoop(List<Integer> numbers)
{
    int sum=0;
    for(int i=0;i<numbers.size();i++)
    {
        sum=sum+numbers.get(i);
    }
    return sum;
}
public static int sumOfNumbersUsingIterableInterface(List<Integer> numbers) 
{
    int sum=0;
    ListIterator<Integer> iterator=numbers.listIterator();
    while(iterator.hasNext())
    {

            sum=sum+iterator.next();

    }
    return sum;
}
public static int sumOfNumbersUsingEnhancedForLoop(List<Integer> numbers) 
{
    int sum=0;
    for(int number:numbers)
    {
        sum=sum+number;
    }
    return sum;
}
public static int sumOfNumbersUsingLambdaExpression(List<Integer> numbers) 
{
    return numbers.stream().parallel().reduce(0, (e,num)->e+num);
}

All of these methods return 137 as the result.For me using lambda expression for evaluating the sum is found to be convenient.However I am not sure about its performance if the size of the list grows high.It will be very useful if someone can illustrate a performance comparison of all the methods.

Kiran Muralee
  • 2,068
  • 2
  • 18
  • 25
  • 3
    Why don't you write teh performance comparison code, then report back to us which is faster? – Software Engineer Jun 04 '15 at 14:38
  • 1
    Performance depends on the list implementation. `get` is quite fast on an `ArrayList`. On a `LinkedList` iteration is much faster than `get`. – phlogratos Jun 04 '15 at 14:39
  • `Arrays.asList` just wraps the array. So the first one is most likely fastest. – Bubletan Jun 04 '15 at 14:40
  • @engineer Dollery Yes sir I will do it and update .But my point is that a specific justification of the reason why one method is faster than the other or why one may become slower. – Kiran Muralee Jun 04 '15 at 14:44
  • 2
    For microbenchmarks you should use [JMH](http://openjdk.java.net/projects/code-tools/jmh/). Also, your last example is not equivalent to the others. – the8472 Jun 04 '15 at 14:46
  • @the8472 http://stackoverflow.com/questions/26252672/java8-lambda-performance-vs-public-functions helped – Kiran Muralee Jun 04 '15 at 15:00
  • 3
    If you only have ten items in your list, the performance differences are likely to be irrelevant (and the stream implementation won't even bother trying to parallelize). You should focus performance analysis where it will actually make a difference in your program. The rest of the time, choose the version that is most readable and maintainable. – Brian Goetz Jun 04 '15 at 16:01

2 Answers2

2

In your case, a sequential stream can't be faster than the for loops (the stream will loop over the list too, but with some overhead). The for loops should be equivalent.

This is even more the case that your stream example incurs a lot more boxing/unboxing operations than the for loop versions. You could improve that with:

return numbers.parallelStream().mapToInt(Integer::intValue).sum();

A parallel stream may be faster if your list is large (my guess is: above 10k+ elements - below that the overhead of parallelisation will probably be too high).

If you really need performance, you should work with primitives...

assylias
  • 321,522
  • 82
  • 660
  • 783
  • the JVM can eliminate autoboxing in some scenarios. this one is simple enough that it may be able to do so, i.e. a sequential stream using boxed ints could end up having the same performance as the primitive loops, after optimization. – the8472 Jun 04 '15 at 14:59
1

The only hypothetical performance problem you may run into with the lambda example is that it parallelizes. That causes the JVM to spin up some threads which has an inherent overhead cost, plus the cost of communication obviously. That said, if you were working on a billion integers at once, the parallelized version will likely run a good deal faster in most scenarios. It will have performance problems if you're trying to run it A LOT just because of the lack of cores and physical CPUs. You could more easily predict the cost with a single threaded example, but as long as it's not being called many times (like by a really commonly used REST API), it'll run faster on big lists.

Mike Thomsen
  • 36,828
  • 10
  • 60
  • 83