繁体中文
设为首页
加入收藏
当前位置:.Net技术首页 >> VB.Net语言 >> ReDim Preserve 執行效能上的陷阱(转)

ReDim Preserve 執行效能上的陷阱(转)

2004-10-01 08:26:10  作者:  来源:互联网  浏览次数:13  文字大小:【】【】【
简介:ReDim Preserve 執行效能上的陷阱在 VB 任何使用過陣列的人一定非常熟悉使用 ReDim 陳述來改變陣列大小,今天, 我將詳細說明為什麼將來最好不要使用這樣的陳述語法,或是至少要很小心考慮使用到它。 ReDim 可能...

ReDim Preserve 執行效能上的陷阱在 VB 任何使用過陣列的人一定非常熟悉使用 ReDim 陳述來改變陣列大小,今天, 我將詳細說明為什麼將來最好不要使用這樣的陳述語法,或是至少要很小心考慮使用到它。 ReDim 可能上的使用

在還沒開始 ReDim 陳述句之前, 我要藉由程式範例 (redimsamples.aspx) 來說明 ReDim 最普遍的使用方法。使用到 ReDim 以及 ReDim Preserve:

<% @Page Language="VB" %><%Dim arrStrings(1) as StringResponse.Write(UBound(arrStrings) & "
")ReDim arrStrings(20)Response.Write(UBound(arrStrings) & "
")ReDim Preserve arrStrings(25)Response.Write(UBound(arrStrings) & "
")%>

ReDim 允許加大以及縮小陣列大小。因此,一個新的陣列會在每一個 instance 中產生,理由是 VB.NET 陣列是繼承自 .NET Runtime 的 System.Array,而在產生時,根據定義會有一固定大小。在 C# 中這是很明顯的,就如下的程式碼所示是仿效 ReDim:

string[] arrTest = new string[1];// and now we want to change the size: ReDim arrTest(20)arrTest = new string[20];

就其本身來說,這並不是問題,問題在於 Preserve(今日主題)。當使用 Redim 含有 Preserve 關鍵字時,之前的元素被保留 - 就如在新的陣列中複製一樣ReDim Preserve 執行效能上的殺手

原則上,我們已經搞壞了整件事 - ReDim Preserve 陳述句產生一新陣列 - 而之前陣列的元素會複製到新的陣列。這在 VB.NET 環境中會暗自發生 (就如過去的 VB 是一樣情形)。除了執行效能漏失外,並不會察覺。為了能夠突顯這種現象,我設定一個迴圈來 Redim 陣列 5000 次 (redimloop.aspx)。

<% @Page Language="VB" Trace="True" %><%Dim arrStrings() as StringDim i as IntegerTrace.Write("Redim","Start")For i = 1 To 5000 ReDim Preserve arrStrings(i) arrStrings(i-1) = iNextTrace.Write("Redim","End")%>

當我再追蹤時轉換,就很容易得到執行效能上的資料:

當然,隨著每次呼叫(以及使用的機器)每次會有不同表現,但是 至少你已懂得相對的執行效能

但是當呼叫 ReDim Preserve 時會暗地發生什麼事?為了說明這點,在 C# 中我仿效 ReDim 陳述句,就好像在 VB.NET 中使用 ReDim 暗地發生一樣,必須明示出來 (redimloopexplicit.aspx)。

<% @Page Language="C#" Trace="True" %><%string[] arrStrings = new string[1];int i;Trace.Write("Redim","Start");for (i=1;i<=5000;i++){ string[] arrHelper = new string; arrStrings.CopyTo(arrHelper, 0); arrHelper[i-1] = i.ToString(); arrStrings = arrHelper;}Trace.Write("Redim","End");%>

從這我們能明顯看出 - 首先一個新的陣列大小產生,然後先前的陣列內容會複製到新的陣列。 我指派重述的變數在 C# 中轉型為 String,為求完整,我交換了陣列變數。

要是你認為 VB.NET 好像有點不同,那就錯誤了 - 執行效能上完全和 ReDim Preserve 一樣(我的程式碼或許好一點,因為並不需要將減小陣列列入考量)。執行效能的好壞只能藉由與更好的技術作比較才能體會 - ArrayList class。最佳解決方法 - ArrayLists

動態陣列的最佳解決方法是在System.Collections namespace 中使用 ArrayList class。 ArrayList 可以動態的增長或縮小,且容易使用 (arraylistloop.aspx):

<% @Page Language="VB" Trace="True" %><% @Import Namespace="System.Collections" %><%Dim arrList as New ArrayList(100)Dim i as LongTrace.Write("ArrayList","Start")For i = 1 To 50000 arrList.Add(i)NextTrace.Write("ArrayList","End")%>

如果你有注意觀察的話你會注意到迴圈不是跑到 5000 而是 50000,理由是: 使用到 5000,並無法測得執行效能。但是使用 50000 就表現的非常明顯:

執行時間是從 0.02 到 0.6 - 而且是一個有順序的大迴圈。我是要讓 ReDim Preserve 也能隨著重述次數來執行,但是在執行的當中我重新設定 Server 的時間。結論

從這篇文章的課題我們了解到在 VB.NET 環境中 ReDim Preserve 最好避免使用。當需要使用動態的陣列時,建議使用 [I]ArrayList 因為這看起來比較像是正式

责任编辑:admin
相关文章