0

I’m trying to figure out , why compiler looks through the collection using functional style swiftly then imperative. Here is the simple example where functional search goes first and takes 9.5 sec to deal with it , while imperative follows right behind with 10.3. As soon as I rearrange them , and put imperative before functional, results become similar: 10.1 and 10.29


I’ve added some changes based on users responses , which make my code more correct. Now benchmark starts in right moment of time and count time of what I exactly need. But question remains unanswered. Even though I run two independent timers, for every loop, Functional loop complete it’s search much faster then Imperative. 1.03 against 0.3.

import java.util.*;
public class Main
{
    public static void main(String[] args)
    {
    List<Integer> numbers = new ArrayList();
    int size = 200000000;
    //add objects to collection
       for(int i = 0; i <= size; i++)
       {
       numbers.add(i);
       }
    //functional
    long timer = System.nanoTime();
       if(numbers.contains(size))
       {
       System.out.println(System.nanoTime() - timer) / 1000000000.0);
       }
    //imperative
    timer = System.nanoTime();
       for(Integer num : numbers)
       {
          if(num.equals(size))
          {
        System.out.println(System.nanoTime() - timer) / 1000000000.0);
          break;
          }
       }
    }
}

So, question is:

  • Why functional search complete faster?

Appreciate your response

Gipsy King
  • 186
  • 2
  • 2
  • 14
  • Why do you call the `contains` method functional? – Sid Feb 08 '19 at 17:20
  • Not a direct duplicate, but please read https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java and its answers to understand why such a benchmark does not produce valid results. – dunni Feb 08 '19 at 17:26
  • @Sid I haven’t got much knowledge in Java , but it’s written in book : “ Java tutorial 24 hours trainer “ , unit : 13 Lambda expression and functional style programming. I would add picture of page but can’t due to copy right. – Gipsy King Feb 08 '19 at 18:31
  • @dunni now I rectify my code :) – Gipsy King Feb 08 '19 at 23:47
  • Which JDK version are you using? – dunni Feb 09 '19 at 00:07
  • @dunni JDK 9 version – Gipsy King Feb 09 '19 at 00:42

3 Answers3

0

ArrayList uses a similar loop as yours:-

for (int i = start; i < end; i++) {
    if (o.equals(es[i])) {
        return i;
    }
}

So there would be no practical difference in performance.

The small performance difference you see can be seen even if you run the same code multiple times. This can happen due to a variety of factors including CPU scheduling, etc.

Kartik
  • 7,677
  • 4
  • 28
  • 50
0

Watch out where you start and stop your timer. In your code sample, you take the starting time before populating the list. Also, the time differences you calculate make no sense to me. The second one will be the entire running time of the program, not just the duration of the iterative loop.

Try it again like this:

import java.util.*;
public class Main
{
    public static void main(String[] args)
    {
    List<Integer> numbers = new ArrayList<>();

    int size = 200000000;
    //add objects to collection
       for(int i = 0; i <= size; i++)
       {
       numbers.add(i);
       }
    //functional
       long timer = System.nanoTime(); //take start time here
       if(numbers.contains(size))
       {
       System.out.println(System.nanoTime() - timer) / 1000000000.0);
       }
    //imperative
       long timer = System.nanoTime(); //take a new start time for the second test
       for(Integer num : numbers)
       {
          if(num.equals(size))
          {
        System.out.println(System.nanoTime() - timer) / 1000000000.0);
          break;
          }
       }
    }
}
Streamfighter
  • 454
  • 4
  • 15
0

The way you calculated the duration of each operation is off.

  • The first printed duration is actually for how long it takes to add all items to the list AND find the item using contains
  • The second one takes the first duration AND the duration of the last loop

Here's how to fix it

List<Integer> numbers = new ArrayList<>();
int size = 100000;

for (int i = 0; i <= size; i++)
    numbers.add(i);

long timer = System.nanoTime();
if (numbers.contains(size))
    System.out.println((System.nanoTime() - timer) / 1000000000.0);

timer = System.nanoTime();

for (Integer num : numbers) {
    if (num.equals(size)) {
        System.out.println((System.nanoTime() - timer) / 1000000000.0);
        break;
    }
}
molamk
  • 4,076
  • 1
  • 13
  • 22
  • Ok , let’s presume there is just one loop. And timer locates just above loop as in your example. It still goes faster to use contains method instead of equals – Gipsy King Feb 08 '19 at 23:23