日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于for和foreach,兼顾效率与安全

發布時間:2025/5/22 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于for和foreach,兼顾效率与安全 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
對于數組的訪問,是應該使用for的方式的,因為這樣性能更高。以下代碼是恰當的。 Object[]?objArray?=?...;
int?objArrayLength?=?objArray.Length;
for?(int?i?=?0;?i?<?objArrayLength;?++i)
{
????
//?do?something ...
}


String?str?
=?...;
int?strLength?=?str.Length;
for?(int?i?=?0;?i?<?strLength;?++i)?
{
???
//?do?something ...
}

對ArrayList這樣的可使用下標進行隨機訪問的數據結構,使用下標訪問,要比foreach的方式進行順序訪問,速度要快一些。foreach這樣寫法,使用的過程產生一個額外的對象Enumerator,而且每次訪問需要更多的操作,降低性能。下面的兩種寫法編譯出的代碼是一樣的:
第一種寫法:
IList?list?=?new?ArrayList();
IEnumerator?iter?
=?list.GetEnumerator();
try
{
????
while?(iter.MoveNext())
????
{
????????Object?obj?
=?iter.Current;
????????
//do?something?...
????}

}

finally
{
????IDisposable?disposableObj?
=?iter?as?IDisposable;
????
if?(disposableObj?!=?null)
????
{
????????disposableObj.Dispose();
????}

}

第二種寫法: IList?list?=?new?ArrayList();
foreach?(Object?obj?in?list)
{
????
//do?something?...
}

對比這兩種寫法,第一種寫法非常羅嗦,所以C#引入了foreach的語法。通過觀察第一種寫法,foreach是通過GetEnumerator獲得一個IEnumerator對象,通過IEnumerator對象執行MoveNext()方法和獲取Current屬性進行遍歷的。

我們再通過Reflector工具,查看mscorlib.dll中System.Collection.ArrayList的實現: //為了簡單起見,我只列出ArrayList的Add、Clear、GetEnumerator的代碼
public?class?ArrayList
{
????
//這是一個版本標識,ArrayList對象,每做一個修改操作,_version都會加1
????private?int?_version;

????
public?virtual?int?Add(object?value)
????
{
????????
int?num1;
????????
if?(this._size?==?this._items.Length)
????????
{
????????????
this.EnsureCapacity((this._size?+?1));
????????}

????????
this._items[this._size]?=?value;
????????
++this._version;?//注意此處
????????this._size?=?((num1?=?this._size)?+?1);
????????
return?num1;
????}


????
public?virtual?void?Clear()
????
{
????????Array.Clear(
this._items,?0,?this._size);
????????
this._size?=?0;
????????
++this._version;?//注意此處
????}


????
//每次調用GetEnumerator方法,都會構造一個FastArrayListEnumerator
????
//或者ArrayListEnumeratorSimple對象。
????public?virtual?IEnumerator?GetEnumerator()
????
{
????????
if?(base.GetType()?==?typeof(ArrayList))
????????
{
????????????
return?new?ArrayList.FastArrayListEnumerator(this);
????????}

????????
return?new?ArrayList.ArrayListEnumeratorSimple(this);
????}

}

通過上述代碼可以看到,ArrayList是通過_version成員變量作版本標識的,每次執行Add、Clear等修改ArrayList內容的操作,都會將版本號加1,而每次調用GetEnumerator方法,都會構造一個FastArrayListEnumerator或者ArrayListEnumeratorSimple對象。我們再看FastArrayListEnumerator的實現: class?FastArrayListEnumerator
{
????
private?int?version;

????
internal?FastArrayListEnumerator(ArrayList?list)
????
{
????????
this.list?=?list;
????????
this.index?=?-1;

????????
//獲取構建FastArrayListEnumerator對象時ArrayList的版本號
????????this.version?=?list._version;?

????????
this.lastIndex?=?(list._size?-?1);
????}


????
public?bool?MoveNext()
????
{
????????
int?num1;

????????
//比較ArrayList當前的版本號,
????????
//是否和構建FastArrayListEnumerator對象時的版本號一致
????????
//如果不一致,則拋出異常。
????????if?(this.version?!=?this.list._version)
????????
{
????????????
throw?new?InvalidOperationException(
????????????????Environment.GetResourceString(
"InvalidOperation_EnumFailedVersion")
????????????????);
????????}


????????
//... ...?
????}

}

FastArrayListEnumerator對象構建時,當時時ArrayList的版本號。當執行MoveNext()操作時,檢查ArrayList當前的版本號是否和FastArrayListEnumerator對象構建時的版本號一致,如果不一致就會拋出異常。

由于Enumerator中,做了版本檢查處理的工作,所以使用foreach是線程安全,而使用for則不時。為什么呢?如果在使用foreach遍歷對象的過程中,其他線程修改了List的內容,例如添加或者刪除,就會出現不可知的錯誤,而使用foreach則能夠正確拋出錯誤信息。

綜上所述,結論如下:
使用for,更高效率。
使用foreach,更安全。

那么如何選擇呢?我的建議是,在一些全局的,多線程可以訪問的數據結構對象,使用foreach。而對本地變量,則使用for,效率和安全兼顧!例如: public?void?F1(IList?globalList)
{
????IList?waitForDeleteList?
=?new?ArrayList();

????
//全局變量,使用foreach,保證線程
????foreach?(Object?item?in?globalList)
????
{

????????
if?(condition)
????????
{
????????????waitForDeleteList.Add(item);
????????}

????}


????
//本地變量使用for,保證效率
????int?waitForDeleteListCount?=?waitForDeleteList.Count;
????
for?(int?i?=?0;?i?<?waitForDeleteListCount;?++i)
????
{
????????globalList.Remove(waitForDeleteList[i]);
????}

}

以上建議,對于在Java環境下也使用,我閱讀過JDK 1.4的java.util.ArrayList的實現,.NET Framework的實現和JDK的實現,幾乎是一樣的,是否抄襲,見仁見智。上述的C#代碼在Java環境中應為: public?void?f1(List?globalList)?{
????List?waitForDeleteList?
=?new?ArrayList();
????
//全局變量,使用Iterator遍歷,保證線程
????Iterator?iter?=?globalList.iterator();
????
while?(iter.hasNext())?{
????????Object?item?
=?iter.next();
????????
if?(condition)?{
????????????waitForDeleteList.add(item);
????????}

????}

????
????
//本地變量使用for,保證效率
????int?waitForDeleteListCount?=?waitForDeleteList.size();
????
for?(int?i?=?0;?i?<?waitForDeleteListCount;?++i)?{
????????globalList.remove(waitForDeleteList.
get(i));
????}

}


注意,以上代碼并不是做該項工作的最優算法,如果需要更高的效率,修改如下:
C#版本
public?void?F1(IList?globalList)
{
????
bool?condition?=?true;
????IList?waitForDeleteList?
=?new?ArrayList();

????
//全局變量,使用foreach,保證線程
????int?itemIndex?=?0;
????
foreach?(Object?item?in?globalList)
????
{
????????
if?(condition)
????????
{
????????????waitForDeleteList.Add(index);
????????}

????????
++itemIndex;
????}


????
//本地變量使用for,保證效率
????int?waitForDeleteListCount?=?waitForDeleteList.Count;
????
for?(int?i?=?waitForDeleteListCount?-?1;?i?>=?0;?--i)
????
{
????????index?
=?(int)?waitForDeleteList[i];
????????globalList.RemoveAt(itemIndex);
????}

}

Java版本:
public?void?f1(List?globalList)?{
????List?waitForDeleteList?
=?new?ArrayList();
????
//全局變量,使用Iterator遍歷,保證線程
????Iterator?iter?=?globalList.iterator();
????
int?index?=?0;
????
while?(iter.hasNext())?{
????????Object?item?
=?iter.next();
????????
if?(condition)?{
????????????waitForDeleteList.add(
new?Integer(index));
????????}

????????
++index;
????}

????
????
//本地變量使用for,保證效率
????int?waitForDeleteListCount?=?waitForDeleteList.size();
????
for?(int?i?=?waitForDeleteListCount?-?1;?i?>=?0;?--i)?{
???????index?
=?((Integer)?waitForDeleteList.get(i)).intValue();
????????globalList.remove(index);
????}

}

轉載于:https://www.cnblogs.com/jobs/archive/2004/07/17/25218.html

總結

以上是生活随笔為你收集整理的关于for和foreach,兼顾效率与安全的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产91在线视频 | 中文字幕欧美人妻精品一区蜜臀 | 操操操操操操 | 4438激情网 | k8yy毛片| 五月天在线播放 | 一本色道久久hezyo无码 | 欧美一区二区在线视频 | 日韩字幕 | 中文有码在线观看 | 人体私拍套图hdxxxx | 隔壁邻居是巨爆乳寡妇 | 国产91一区二区三区在线精品 | 加勒比视频在线观看 | 超碰个人在线 | 播放黄色一级片 | 第一色影院 | 日本九九视频 | 妹子色综合 | 蜜臀999| 91极品蜜桃臀 | 香蕉精品视频在线观看 | 天堂网91 | 精品一区二区三区四区五区六区 | 国产乱码精品一区二区三 | 日本黄色三级网站 | 国产精品视频久久久久 | 西西4444www大胆无码 | av在线片 | 性插视频在线观看 | 人妻少妇被猛烈进入中文字幕 | 成人a毛片久久免费播放 | 国模小黎自慰gogo人体 | 韩国美女福利视频 | 狠狠操很很干 | 五月激情片 | 琪琪色av| 147人体做爰大胆图片成人 | 美女视频免费在线观看 | 久久久夜 | 日本www高清| 亚洲av无码成人精品国产 | 日本在线中文字幕专区 | 成年人黄视频 | 久久久久久av无码免费看大片 | 中文字幕在线视频不卡 | www.国产视频.com | 91美女诱惑 | 青草在线视频 | 黄视频在线免费看 | 激情爱爱网 | 特级毛片爽www免费版 | 怡红院一区二区三区 | 免费观看一区二区 | 在线免费观看国产精品 | 黑人一级片 | www在线看片| 尤物网站在线观看 | 美女xx网站| 国产精品资源在线 | 国产午夜精品在线 | 手机看片欧美 | 久久久久久久久久电影 | 激情伊人网 | xxx日本少妇 | 亚洲精品综合久久 | 亚州综合 | 国产精品天美传媒沈樵 | 一本久道在线 | v888av| 国产精品二区一区二区aⅴ 一卡二卡三卡在线观看 | 激情五月婷婷久久 | 人与拘一级a毛片 | 蜜桃视频无码区在线观看 | 天天操天天干天天操 | 男女考妣视频 | 精品日韩一区二区三区 | 国产精品久久久久毛片大屁完整版 | 国产精品成人69xxx免费视频 | 日韩一区二区三区在线看 | 亚洲性夜 | aa爱做片免费| 成人乱人乱一区二区三区一级视频 | 女人的洗澡毛片毛多 | 久久久久久久久久一级 | 国产黄色一区二区 | 色综合狠狠爱 | 香蕉视频网页 | 97视频一区 | 亚洲熟女少妇一区二区 | 精品人妻一区二区三区日产乱码 | 免费看v片| 在线播放黄色网址 | 动漫美女舌吻 | 伊人宗合 | 久久国产柳州莫菁门 | avav我爱av| 在线观看成人网 | 精品一区二区三区免费看 |