以下两个片段中的哪一个更快,假设list
是一个ArrayList。
for(int i=0; i<list.size();i++){...}
或
int count = list.size();
for(int i=0; i<count;i++){...}
此外,优化(如果有的话)是否适用于Android的ArrayAdapter?
int sCount = mAdapter.getCount();
澄清
在for循环中,每次编译器调用list.size()
或者调用它一次并随后使用它。
注意每次调用list.size()
实际上都会对项目进行计数。这就是问题的本质。
答案 0 :(得分:3)
在大多数情况下,速度无法区分。也就是说,如果在循环执行时集合可能正在改变,那么你的两个循环在语义上是不同的。集合的修改可以在循环中(或在循环中调用的代码中)或在同时执行的不同线程中。
专门回答您的“澄清”:是的,每次循环都会调用size
方法。
我永远不会写这个循环的“优化”版本,除非我有明确的证据表明优化很重要(并且集合没有改变)。如果您的代码经过如此调整,以至于此类调整可以为您提供可衡量的加速,那么您应该非常高兴。
答案 1 :(得分:2)
你应该问自己一些问题:
如果可以通过YES回答展位问题,那么请尝试双向并分析结果。
事实上,我认为它不会有所作为。
答案 2 :(得分:0)
任何体面的编译器都会将这些编译为完全相同的汇编代码。
答案 3 :(得分:0)
int count = list.size();
for(int i=0; i<count;i++){...}// Is faster
答案 4 :(得分:0)
我猜这些编译成同样的东西,因此速度是一样的。
不确定Android的ArrayAdapter。
答案 5 :(得分:0)
ArrayList list = new ArrayList();
for(int i=0; i<1000000;i++){
list.add("Object added "+i);
}
long startTime =System.currentTimeMillis();
for(int i=0; i<list.size();i++){
System.out.println(list.get(i));
}
long endTime = System.currentTimeMillis();
int count=list.size();
long startTime1 =System.currentTimeMillis();
for(int i=0; i<count;i++){
System.out.println(list.get(i));
}
long endTime1 = System.currentTimeMillis();
System.out.println("Exe1 time in millis secs"+(endTime-startTime));
System.out.println("Exe2 time in millis secs"+(endTime1-startTime1));
OutPut
...........
.............
Object added 999999
Exe1 time in millis secs14131
Exe2 time in millis secs14106
答案 6 :(得分:0)
我认为第二段代码稍快一些。方法调用可能需要将代码加载到内存中,并将数据从方法内存堆栈加载到方法内存堆栈(如第一段代码中所示)。这显然比单个内存访问(第一段代码)慢。但是,如果在循环迭代期间数组大小可能会发生变化,我认为使用第一段代码会更安全。请考虑以下示例:
for(int i=0; i<list.size();i++){
if list.get(i) == 0 { list.remove(i); i--; }
}
上面的示例从数组中删除null元素。因此,每次删除元素时,数组大小都会减小。如果你不使用list.size()并忘记适当地更新数组的大小,你将最终得到“索引越界”异常。