循环效率

时间:2010-10-20 08:45:01

标签: android loops performance

我在Dalvik VM上通过演示文稿(dalvik-vm-internals)看到了以下循环,我们有使用(2)和(3)并且避免(7)

(1)for(int i = initializer; i> = 0; i - )

(2)int 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 ++)

(5)for(int i = 0; i< this.var; i ++)

(6)for(int i = 0; i< obj.size(); i ++)

(7)Iterable list = get list; for(Type obj:list)

评论:我觉得(1)和(2)是一样的。 (3) (4)每次必须计算数组的长度,这样就可以避免了 (5) (6)与(4)相同,每次计算大小 (7)要求避免因为列表属于Iterable类型??

还有一个,如果我们有无限数据(假设数据是一个流),我们应考虑哪个循环以获得更高的效率?)

请您对此发表评论......

3 个答案:

答案 0 :(得分:0)

对于无限数据,没有一个例子足够好。最好的办法是

for(;;) {
   list.poll(); //handle concurrency, in java for example, use a blocking queue
}

答案 1 :(得分:0)

如果这是他们推荐的内容,那就是他们为编译器和VM优化的内容。您认为相同的方式不一定以相同的方式实现:编译器可以使用各种技巧和数据以及路径分析来避免极其昂贵的操作。例如,array.length()结果可以缓存,因为数组是不可变的。

他们从最高效率到最低效率排名:但是(1)是“不自然的”。我同意,不是吗? (7)的问题是迭代器对象被创建并且必须是GC。

在注意建议时请仔细注意。它显然是针对已知集合的有界迭代,而不是流案例。只有当环路对性能和能耗(“在计算机规模上运行”)产生重大影响时才有意义。优化的第一定律是“不优化”。第二定律(专家)是“不要优化,但是。”。首先测量(执行时间和CPU消耗),稍后优化:这甚至适用于移动设备。

您应该考虑的是前面的幻灯片:尝试尽可能经常地睡觉,同时快速响应变化。你如何做到这一点取决于你正在处理什么样的流。

最后,请注意该演示文稿已有两年的历史,并且可能无法完全应用于实现JIT的2.2设备。

答案 2 :(得分:0)

1)和2)真的不同。 2)需要额外的减法来计算i = 0不需要。 更好的是,在大多数处理器(以及优化良好的代码)上,i> = 0不需要进行比较。处理器可以使用negative flag,导致最后一次递减(i - )。

所以循环-1的结尾看起来像(在伪汇编程序中)

--i
jump-if-neg

while loop#2

++i
limit-i  # set negative flag if i >limit
jump-if-neg

除非循环中的代码非常小(如基本的C字符串操作),否则这并没有太大区别 这可能不适用于解释语言。