测试for和foreach的执行效率的问题
在 [C#语言] C#语言中又一个自认为不太理想的地方。。。 里面讨论过
观点:foreach的效率比for要低得多?
当时我很反对,而且前段时间做过相关测试,看过分析文章
《[测试分析] for与foreach 执行效率测试结果》
http://www.zj55.net/article/html/s816/8626.htm
文章结论:相对于原来的for语句foreach具有更好的执行效率,foreach的平均花费时间只有for30%。
通过测试结果在for和foreach都可以使用的情况下,我们推荐使用效率更高的foreach.在测试同时
我们附加的发现,用for写入数据时间大约是读取数据时间的10倍左右
一直以为foreach比for执行效率高
但是今天做了个简单的测试结果却不是这样,难道是我测试方法不对?
我的测试方案:
//核心代码
private void btnExecFor_Click(object sender, System.EventArgs e)
{
long iCount = 0;
iCount = Convert.ToInt64(this.textBox1.Text.Trim());
double[] dArray = new double[iCount];
for(int i = 0;i <= iCount-1;i++)
{
dArray[i] = i;
}
//开始执行for
string strBeginTime = DateTime.Now.Second.ToString() +" " +DateTime.Now.Millisecond.ToString();
double iSum = 0;
for(int i = 0;i<=iCount-1;i++)
{
iSum += dArray[i];
}
string strEndTime = DateTime.Now.Second.ToString() +" " +DateTime.Now.Millisecond.ToString();
this.lFor.Text = "执行FOR-开始时间:"+strBeginTime+" 结束时间:"+strEndTime;
}
private void btnExcForeach_Click(object sender, System.EventArgs e)
{
long iCount = 0;
iCount = Convert.ToInt64(this.textBox1.Text.Trim());
double[] dArray = new double[iCount];
for(int i = 0;i <= iCount-1;i++)
{
dArray[i] = i;
}
//开始执行
string strBeginTime = DateTime.Now.Second.ToString() +" " +DateTime.Now.Millisecond.ToString();
double iSum = 0;
foreach(int j in dArray)
{
iSum += j;
}
string strEndTime = DateTime.Now.Second.ToString() +" " +DateTime.Now.Millisecond.ToString();
this.lForeach.Text = "执行FOREACH-开始时间:"+strBeginTime+" 结束时间:"+strEndTime;
}
private void btnExecFor_Click(object sender, System.EventArgs e)
{
long iCount = 0;
iCount = Convert.ToInt64(this.textBox1.Text.Trim());
double[] dArray = new double[iCount];
for(int i = 0;i <= iCount-1;i++)
{
dArray[i] = i;
}
//开始执行for
string strBeginTime = DateTime.Now.Second.ToString() +" " +DateTime.Now.Millisecond.ToString();
double iSum = 0;
for(int i = 0;i<=iCount-1;i++)
{
iSum += dArray[i];
}
string strEndTime = DateTime.Now.Second.ToString() +" " +DateTime.Now.Millisecond.ToString();
this.lFor.Text = "执行FOR-开始时间:"+strBeginTime+" 结束时间:"+strEndTime;
}
private void btnExcForeach_Click(object sender, System.EventArgs e)
{
long iCount = 0;
iCount = Convert.ToInt64(this.textBox1.Text.Trim());
double[] dArray = new double[iCount];
for(int i = 0;i <= iCount-1;i++)
{
dArray[i] = i;
}
//开始执行
string strBeginTime = DateTime.Now.Second.ToString() +" " +DateTime.Now.Millisecond.ToString();
double iSum = 0;
foreach(int j in dArray)
{
iSum += j;
}
string strEndTime = DateTime.Now.Second.ToString() +" " +DateTime.Now.Millisecond.ToString();
this.lForeach.Text = "执行FOREACH-开始时间:"+strBeginTime+" 结束时间:"+strEndTime;
}
执行效果图:
测试结果:
数组长度 | 1000000 | 10000000 | 50000000 |
for执行时间(毫秒) | 15 | 156 | 704 |
foreach执行时间(毫秒) | 62 | 578 | 2065 |
看到这个结果,我汗了,差别太大了,也许是例子简单?
大家也来分析分析,是谁的对?
………………………………………………
分析结果-即时更新
分析一:
用Reflector.exe反编ForVsForeach.exe
foreach(int j in dArray)
{
iSum += j;
}
居然变成了
for (int num7 = 0; num7 < numArray2.Length; num7++)
{
int num4 = (int) numArray2[num7];
num3 += num4;
}
难道foreach在最后还是要编译成for运行?
分析二:
by fadingflower:
你的这个例子不合适,不应该用valuetype做测试,应该用object
分析三:
by Cajon's Blog
在《[测试分析] for与foreach 执行效率测试结果》中测试对象是DataTable,测试结果当然是Foreach快,因为它里面是用链表存储数据。使用枚举器遍历链表自然要比用Indexer遍历链表要快。
在文中的例子中,测试对象是数组,使用Indexer遍历数组自然就比使用枚举器遍历数组要快了。
分析四:
by juqiang
box/unbox,装箱拆箱,对foreach是主要影响
分析五:
by Laser.NET
针对数组这样的基本类型由于编译器优化的缘故,运行效率应该是差不多。
如果是其他的复杂的集合类型或者是自定义的数据类型就要看具体的enumerator和indexer的实现了:)