通过Java List高效循环

use*_*800 16 java optimization android dalvik

以下列表来自2008年的谷歌I/O演讲,称为"Dalvik虚拟机内部",它列出了从最高效率到最低效率循环遍历一组对象的方法:

(1) for (int i = initializer; i >=0; i--) //hard to loop backwards
(2) int limit = calculate_limit(); for (int i= 0; i< limit; i++)
(3) Type[] array = get_array(); for (Type obj : array)
(4) for (int i =0; i< array.length; i++) //gets array.length everytime
(5) for (int i=0; i < this.var; i++) //has to calculate what this.var is
(6) for (int i=0; i < obj.size(); i++) //even worse calls function  each time
(7) Iterable list = get_list(); for (Type obj : list) //generic object based iterators slow!
Run Code Online (Sandbox Code Playgroud)

前三个处于相同的效率区域,如果可能的话,避免使用7个.这主要是帮助电池寿命的建议,但也可能有助于java SE代码.

我的问题是:为什么(7)慢,为什么(3)好?我认为它可能是(3)和(7)的数组和列表之间的区别.另外,正如Dan提到的那样(7)创建了大量的临时对象,这些对象必须是GCed,现在我对Java有点生疏,有人可以解释为什么吗?这是在他的谈话视频 0:41:10一分钟.

Dal*_*mas 7

这个列表有点过时了,今天应该没用.

几年前,当Android设备速度缓慢且资源非常有限时,这是一个很好的参考.Dalvik VM实现也缺乏当今可用的大量优化.

在这样的设备上,简单的垃圾收集很容易花费1或2秒(相比之下,今天大多数设备需要大约20ms).在GC期间,设备刚刚冻结,因此开发人员必须非常小心内存消耗.

今天你不必过于担心,但如果你真的关心性能,这里有一些细节:

(1) for (int i = initializer; i >= 0; i--) //hard to loop backwards
(2) int limit = calculate_limit(); for (int i=0; i < limit; i++)
(3) Type[] array = get_array(); for (Type obj : array)
Run Code Online (Sandbox Code Playgroud)

这些很容易理解.i >= 0评估的速度要快,i < limit因为它在进行比较之前不会读取变量的值.它直接使用整数文字,速度更快.

我不知道为什么(3)应该比(2)慢.编译器应该产生与(2)相同的循环,但是此时Dalvik VM可能没有正确地优化它.

(4) for (int i=0; i < array.length; i++) //gets array.length everytime
(5) for (int i=0; i < this.var; i++) //has to calculate what this.var is
(6) for (int i=0; i < obj.size(); i++) //even worse calls function  each time
Run Code Online (Sandbox Code Playgroud)

这些已在评论中解释.

(7) Iterable list = get_list(); for (Type obj : list)
Run Code Online (Sandbox Code Playgroud)

Iterables 因为它们分配内存,执行一些错误处理,在内部调用多个方法,所以这一切都很慢......所有这些都比(6)慢得多,每次迭代只调用一个函数.


sri*_*lla 0

我猜你必须将对象编组到基于“链表”的迭代器中,然后支持 API,而不是一块内存和一个指针(数组)