REDIM陷阱(很多人都看过了吧)

<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 728x15, 创建于 08-4-23MSDN */ google_ad_slot = "3624277373"; google_ad_width = 728; google_ad_height = 15; //--> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 160x600, 创建于 08-4-23MSDN */ google_ad_slot = "4367022601"; google_ad_width = 160; google_ad_height = 600; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
  文章标题:REDIM Preserve 執行效能上的陷阱

Christoph Wille   aspxcn.com   2002-07-24  

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

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

<% @Page Language="VB" %>
<%
Dim arrStrings(1) as String
Response.Write(UBound(arrStrings) & "<br>")

REDIM arrStrings(20)
Response.Write(UBound(arrStrings) & "<br>")

REDIM Preserve arrStrings(25)
Response.Write(UBound(arrStrings) & "<br>")
%>

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 String
Dim i as Integer

Trace.Write("REDIM","Start")

For i = 1 To 5000
  REDIM Preserve arrStrings(i)
  arrStrings(i-1) = i
Next

Trace.Write("REDIM","End")
%>

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


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

但是當呼叫 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[i];
  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 Long

Trace.Write("ArrayList","Start")

For i = 1 To 50000
  arrList.Add(i)
Next

Trace.Write("ArrayList","End")
%>

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

11AI93502055430.jpg

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


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

 
11AI9350C0D3X.jpg
seover="window.status='正文--REDIM陷阱很多人都看过了吧)';return true">
<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 728x15, 创建于 08-4-23MSDN */ google_ad_slot = "3624277373"; google_ad_width = 728; google_ad_height = 15; //--> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 160x600, 创建于 08-4-23MSDN */ google_ad_slot = "4367022601"; google_ad_width = 160; google_ad_height = 600; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
阅读更多
个人分类: .net
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭