Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么数组比ArrayList快得多?_Java_Performance - Fatal编程技术网

Java 为什么数组比ArrayList快得多?

Java 为什么数组比ArrayList快得多?,java,performance,Java,Performance,最近,我试图解决这个问题。为此,我首先创建了一个包含所有丰富数字的列表,称为丰富数 接下来,我迭代这个列表,并构建另一个列表,其中包含低于某个限制的大量数字的总和。现在我注意到了一些奇怪的事情。我使用嵌套循环在列表上迭代两次。但是,如果我使用数组存储总和,需要几秒钟的时间,如果我将总和添加到ArrayList,则需要几个小时。原因是什么?我认为代价高昂的操作是两个嵌套循环,但代价高昂的操作似乎是ArrayList#add。有什么线索说明为什么会这样吗 下面是数组的代码: for (int i =

最近,我试图解决这个问题。为此,我首先创建了一个包含所有丰富数字的列表,称为
丰富数

接下来,我迭代这个列表,并构建另一个列表,其中包含低于某个限制的大量数字的总和。现在我注意到了一些奇怪的事情。我使用嵌套循环在列表上迭代两次。但是,如果我使用数组存储总和,需要几秒钟的时间,如果我将总和添加到ArrayList,则需要几个小时。原因是什么?我认为代价高昂的操作是两个嵌套循环,但代价高昂的操作似乎是ArrayList#add。有什么线索说明为什么会这样吗

下面是数组的代码:

for (int i = 0; i < abundants.size(); i++) {
   for (int j = 0; j < abundants.size(); j++) {
      int tot = abundants.get(i) + abundants.get(j);
      if (tot <= limit)
         isSum[tot] = true;
      }
   }
}
for(int i=0;iif(tot因为
int
Integer
快得多


尝试在第一种情况下使用
Integer[]
,或者在第二种情况下使用
TIntArrayList
进行比较。

您的ArrayList实现是O(n^3),而另一种是O(n^2):
sums.contains(…)
必须为内部循环的每次迭代遍历整个
sums
列表。

如果您知道(最大值)元素数,尝试使用给定大小初始化数组列表:

ArrayList<Integer> sums = new ArrayList<Integer>(abundants.size() * abundants.size());
ArrayList sums=新的ArrayList(abundants.size()*abundants.size());

这样就不必调整ArrayList的大小,这将提高速度。

您的代码不是等效的,
.contains()
比您使用原始数组的成本更高。
.contains()
每次调用时都会遍历整个数组,但在基于原始数组的版本中不会这样做。

我认为问题在于
数组列表#contains
,它必须遍历整个列表,从而将复杂性提高到O(n^3),而不是O(n^2)程序的#1。

我不是专家,但取决于
包含的大小()
如果不能执行二进制搜索,可能会变得昂贵。是的,但这是几秒钟而不是几小时的原因吗?使用
BitSet
会更好。这是因为Java没有生成int、long、float和其他一级对象……虽然
int
Integer
更快,但需要
extremely
特殊情况会导致减速3000倍(如问题中所述,小时与秒)@meriton,这是真的。我没有抓住这一点。根据情况,改善的可能性更大,可能是20%到300%。一般的规则是,在比较两件事时,要逐个比较,不要以不同的方式使用。;)contains()仍然需要遍历整个ArrayList,因此速度的提高是有限的。最好尝试将运行时复杂性从O(n^3)更改为更合理的。请您添加一个可能的解决方案(如果您知道的话),因为我对此也很感兴趣。@Bobby,@Roflcoptr,
if(!sums.contains(s)&&s
应该是
如果(这真的能成为几秒钟而不是几小时的原因吗?这真的取决于所有这些列表有多大,但可以是!)所以…如果你有20000个元素在
丰富的
中,你将经历20000*20000次。对于每一次,你都在做一些事情。如果你在最坏的情况下,在每一次迭代中多做20000个操作,这可能需要数小时或数天。
ArrayList<Integer> sums = new ArrayList<Integer>(abundants.size() * abundants.size());