Java ArrayList与C ++ std :: vector

时间:2018-11-16 20:53:38

标签: java c++ collections

我只是试图比较在Java和C ++之间过滤列表的速度。只是为了好玩,因为我已经看到C ++具有std :: vector.erase()可以在适当的位置删除向量的元素,所以我期望它比Java等效的要快得多,这是Java中的代码:< / p>

public static void main(String[] args) {

    List<Integer> ints = new ArrayList<>(100000000);
    long t1, t2;
    int i;
    t1 = System.currentTimeMillis();
    for (i = 0; i < 100000000; i++) {
        ints.add(i);
    }
    t2 = System.currentTimeMillis();

    System.out.println("Initial array generated in " + (t2 - t1) + "ms");

    t1 = System.currentTimeMillis();
    List<Integer> result = ints.stream().filter((e) -> e % 2 == 0).collect(Collectors.toList());
    t2 = System.currentTimeMillis();


    System.out.println("Result: " + result.size() + " in " + (t2 - t1) + "ms.");
}

输出:

Initial array generated in 21859ms
Result: 50000000 in 3135ms.

相当于C ++:

#include <iostream>
#include <vector>
#include <algorithm>
#include <sys/time.h>

long gettime(){

   struct timeval time;
   gettimeofday(&time, NULL);

   long microsec = ((unsigned long long)time.tv_sec * 1000000) + time.tv_usec;

   return microsec / 1000;

}
int main(int argc, char **argv){

  std::vector<int> ints;

  long t1 = gettime();
  for(int i=0; i< 100000000; i++){
    ints.push_back(i);
  }
  long t2 = gettime();

  std::cout << "Initial array generated in " << (t2-t1) << "ms\n";


  t1 = gettime();
  ints.erase(std::remove_if(begin(ints), end(ints),
               [](const int i){ return i%2==0;}), end(ints));

  t2 = gettime();
  std::cout << "Result: " << ints.size() << " in " << (t2-t1) << "ms.\n";

 return 0;
}

和C ++输出:

Initial array generated in 1357ms
Result: 50000000 in 1323ms.

好的,所以数组过滤在C ++中快了3倍(说实话,我期望更多)。但是问题是,为什么Java填充列表的速度如此之慢(22秒)?

1 个答案:

答案 0 :(得分:0)

在Java ArrayList中,每个元素都是一个对象引用。填充列表时,您的代码在堆上分配了近1亿个新对象。对象分配不是很快,这解释了为什么需要22秒。

为避免分配对象,请使用基本类型的数组(例如int[])。不幸的是,Java泛型无法使用原始类型进行参数化,因此在这种情况下,您不能使用ArrayList和其他标准集合。