我有一个循环,其中n非常大。我有一个arraylist alist,它会在每次循环后逐个添加元素。有没有任何优化此循环的方法,以便代码运行得更快或任何其他方法并行添加元素。 提前谢谢。
for(int i=0;i<=n;i++)
{
/ *
some code
*/
alist.add(element);
}
答案 0 :(得分:2)
实例化数组列表时,请确保使用单个参数构造函数:
ArrayList</*your type*/>(n + 1)
这会将ArrayList
的容量设置为所需的元素数量。这样做可以防止内存重新分配,这将有助于运行时性能。它没有限制 ArrayList
容量,但建议对象可以获得那么大的容量。
至于进一步的优化,这实际上取决于/*some code*/
是否是瓶颈;它可能是。
答案 1 :(得分:2)
实际上并行执行 (在多个线程上)可能更慢因为它们都处于争用状态,因为你必须序列化对{{ 1}}。
关于您唯一可以实际做的事情(根据问题中的小信息)确保ArrayList
在开始时具有足够的容量以用于您的所有元素要添加,所以它不需要像你一样去做一堆重新分配。假设您已经有ArrayList
,请拨打ensureCapacity
:
alist
如果你不已经拥有alist.ensureCapacity(alist.size() + n + 1); // +1 because you're adding n+1 elements
for (int i = 0; i <= n; i++) { // Note this loops n+1 times
alist.add(/*...some element...*/);
}
,你可以通过给构造函数提供一个参数来实现:
alist
如果不这样做,alist = new ArrayList(n + 1);
for (int i = 0; i <= n; i++) {
可能必须在循环期间重复重新分配数组,这比在开始时执行一次要慢。
如果您已经拥有某种类型的集合,并且正在将该集合中的所有元素添加到ArrayList
,而不是自己动手,则可以使用alist
。但这基本上只是addAll
后跟一堆ensureCapacity
。
答案 2 :(得分:1)
如果您使用的是ArrayList
,那么推测订单很重要。在这种情况下,您实际上无法使用传统技术在不同的线程中添加元素。它们最终仍然必须按顺序处理才能以正确的顺序添加。
根据您的应用程序,可以使用Java 8线程。如果可以并行处理每个元素,则可以独立地执行每个步骤,然后将结果收集到列表中。类似的东西:
List<Element> result = IntStream.range(0, n).parallel()
.mapToObj(n -> codeCreatingElement(n)).collect(Collectors.toList());