[原创]如何改善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
{
structEmployee
{
PrivateFields#regionPrivateFields
privatestring_employeeID;
privatestring_name;
privateint_age;
#endregion


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

#endregion


PublicProperties#regionPublicProperties

publicstringEmployeeID
{
get{return_employeeID;}
set{_employeeID=value;}
}


publicstringName
{
get{return_name;}
set{_name=value;}
}


publicintAge
{
get{return_age;}
set{_age=value;}
}


#endregion


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

#endregion

}


classEmployeeList:IEnumerable
{
privateEmployee[]_employees;

publicEmployee[]Employees
{
get{return_employees;}
set{_employees=value;}
}


IEnumerableMembers#regionIEnumerableMembers

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


#endregion

}


classEmployeeEnumerator:IEnumerator
{
privateEmployee[]_employees;
privateint_index=-1;

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


IEnumeratorMembers#regionIEnumeratorMembers

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

}


publicboolMoveNext()
{
Console.WriteLine(
"EmployeeEnumerator.MoveNextisinvoked");

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

returnfalse;
}


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

#endregion

}

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

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

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

}

}

}

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

[原创]如何改善Managed Code的Performance和Scalability系列之一:由for V.S. for each想到的
在上面的Sample中我们先定义了一个Employee的struct,之所以使用struct而不用一般的class,我将在后面的部分介绍。

struct Employee
{
PrivateFields#regionPrivateFields
privatestring_employeeID;
privatestring_name;
privateint_age;
#endregion


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

#endregion


PublicProperties#regionPublicProperties

publicstringEmployeeID
{
get{return_employeeID;}
set{_employeeID=value;}
}


publicstringName
{
get{return_name;}
set{_name=value;}
}


publicintAge
{
get{return_age;}
set{_age=value;}
}


#endregion


Tostring#regionTostring
publicoverridestringToString()
{
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()
<
分享到:
评论

你可能感兴趣的:(Blog,performance)