[原创]如何改善Managed Code的Performance和Scalability系列之一:由for V.S. for each想到的...

一直想写一系列如何提高Performance和Scalability的文章,把我的相关经验和所知道的相关的技巧同大家分享。前一阵在园子里有一篇讨论for each 和 for两种循环那个具有更好的performance的blog,议论得沸沸扬扬。我觉得这是一个很好的切入点,我就已此作为引子,开始我的这个系列的文章。这篇文章的重点不是在于比较这两种循环孰优孰劣,我将讨论的重点是如何更好地定义Collection,如何在判断在什么时候该用Array,什么时候用Collection。

一、for each的本质

我们知道,所有实现了System.Collections. IEnumerable接口的类,我们都可以对它运用for each loop。为了弄清楚它的执行过程,我先给出一个Sample:

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Artech.CustomCollection
ExpandedBlockStart.gifContractedBlock.gif
{
structEmployee
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
ContractedSubBlock.gifExpandedSubBlockStart.gif
PrivateFields#regionPrivateFields
privatestring_employeeID;
privatestring_name;
privateint_age;
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif
Constructor#regionConstructor
publicEmployee(stringemployeeID,stringname,intage)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this._employeeID=employeeID;
this._name=name;
this._age=age;
}

#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif
PublicProperties#regionPublicProperties

publicstringEmployeeID
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif
get{return_employeeID;}
ExpandedSubBlockStart.gifContractedSubBlock.gif
set{_employeeID=value;}
}


publicstringName
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif
get{return_name;}
ExpandedSubBlockStart.gifContractedSubBlock.gif
set{_name=value;}
}


publicintAge
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif
get{return_age;}
ExpandedSubBlockStart.gifContractedSubBlock.gif
set{_age=value;}
}


#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif
Tostring#regionTostring
publicoverridestringToString()
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
returnstring.Format("\tID:\t{0}\n\tName:\t{1}\n\tAge:\t{2}\n\t",this._employeeID,this._name,this._age);
}

#endregion

}


classEmployeeList:IEnumerable
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
privateEmployee[]_employees;

publicEmployee[]Employees
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif
get{return_employees;}
ExpandedSubBlockStart.gifContractedSubBlock.gif
set{_employees=value;}
}


ContractedSubBlock.gifExpandedSubBlockStart.gif
IEnumerableMembers#regionIEnumerableMembers

publicvirtualIEnumeratorGetEnumerator()
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
Console.WriteLine(
"EmployeeList.GetEnumerator()isinvoked");
returnnewGenericEmployeeEnumerator(this._employees);
}


#endregion

}


classEmployeeEnumerator:IEnumerator
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
privateEmployee[]_employees;
privateint_index=-1;

publicEmployeeEnumerator(Employee[]employees)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this._employees=employees;
}


ContractedSubBlock.gifExpandedSubBlockStart.gif
IEnumeratorMembers#regionIEnumeratorMembers

publicobjectCurrent
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
get
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
Console.WriteLine(
"EmployeeEnumerator.Currentisinvoked");
returnthis._employees[this._index];
}

}


publicboolMoveNext()
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
Console.WriteLine(
"EmployeeEnumerator.MoveNextisinvoked");

if(this._index<this._employees.Length-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this._index++;
returntrue;
}

returnfalse;
}


publicvoidReset()
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this._index=-1;
}

#endregion

}

classProgram
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
staticvoidMain(string[]args)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gifEmployee[]employees
=newEmployee[]{newEmployee("0001","ZhangSan",21),newEmployee("0002","LiSi",30)};
EmployeeListempoyeeList
=newEmployeeList();
empoyeeList.Employees
=employees;

Console.WriteLine(
"Beginforeachloop");
foreach(EmployeeemployeeinempoyeeList)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
Console.WriteLine(employee.ToString());
}

Console.WriteLine(
"\n\nBeginwhileloop");
IEnumeratorenumerator
=empoyeeList.GetEnumerator();
while(enumerator.MoveNext())
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
Employeeemployee
=(Employee)enumerator.Current;
Console.WriteLine(employee.ToString());
}

}

}

}

我们先运行一下上面的程序再来讲述具体的执行的流程。


在上面的Sample中我们先定义了一个Employee的struct,之所以使用struct而不用一般的class,我将在后面的部分介绍。

struct Employee
ExpandedBlockStart.gifContractedBlock.gif
{
ContractedSubBlock.gifExpandedSubBlockStart.gif
PrivateFields#regionPrivateFields
privatestring_employeeID;
privatestring_name;
privateint_age;
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif
Constructor#regionConstructor
publicEmployee(stringemployeeID,stringname,intage)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this._employeeID=employeeID;
this._name=name;
this._age=age;
}

#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif
PublicProperties#regionPublicProperties

publicstringEmployeeID
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif
get{return_employeeID;}
ExpandedSubBlockStart.gifContractedSubBlock.gif
set{_employeeID=value;}
}


publicstringName
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif
get{return_name;}
ExpandedSubBlockStart.gifContractedSubBlock.gif
set{_name=value;}
}


publicintAge
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif
get{return_age;}
ExpandedSubBlockStart.gifContractedSubBlock.gif
set{_age=value;}
}


#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif
Tostring#regionTostring
publicoverridestringToString()
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
returnstring.Format("\tID:\t{0}\n\tName:\t{1}\n\tAge:\t{2}\n\t",this._employeeID,this._name,this._age);
}

#endregion

}

然后我们基于这个Emplyee struct,定义了与之对应的Collection:EmplyeeList。EmplyeeList实现了System.Collections. IEnumerable接口。并以一个virtual 方法的形式实现了该接口的GetEnumerator方法。(为什么用virtual方法的原因,我会再后续部分解释)。

Public virtual IEnumeratorGetEnumerator()
ExpandedBlockStart.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值