为什么功能样式搜索的运行速度更快,然后在Java中势在必行

时间:2019-02-08 05:20:10

标签: java search functional-programming benchmarking imperative-programming

我试图弄清楚,为什么编译器会迅速使用功能样式浏览集合,然后势在必行。这是一个简单的示例,其中功能搜索排在第一位,处理时间为9.5秒,而紧随其后的是10.3。 一旦我重新排列它们,并在功能上将命令放在首位,结果就会类似:10.1和10.29


我根据用户的响应添加了一些更改,这些更改使我的代码更正确。现在,基准测试会在正确的时间开始,并计算我真正需要的时间。但是问题仍然没有答案。即使我运行两个独立的计时器,对于每个循环,Functional循环仍会比Imperative更快地完成搜索。 1.03对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;
          }
       }
    }
}

所以,问题是:

  • 为什么功能搜索的完成速度更快?

欣赏您的回复

3 个答案:

答案 0 :(得分:0)

ArrayList使用与您类似的循环:-

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

因此,性能上不会有实际差异。

即使多次运行相同的代码,也会看到很小的性能差异。发生这种情况的原因可能是多种因素,包括CPU调度等。

答案 1 :(得分:0)

当心您在哪里开始和停止计时器。在您的代码示例中,您在填充列表之前花费了开始时间。另外,您计算出的时差对我来说毫无意义。第二个将是程序的整个运行时间,而不仅仅是迭代循环的持续时间。

像这样再次尝试:

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;
          }
       }
    }
}

答案 2 :(得分:0)

计算每个操作的持续时间的方式已关闭。

  • 第一次打印的持续时间实际上是将所有项目添加到列表中 并使用contains
  • 查找项目所需的时间
  • 第二个持续时间第一个持续时间 最后一个循环的持续时间

这是解决方法

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;
    }
}