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

  文章标题: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")
%>

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

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

但是當呼叫 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 就表現的非常明顯:

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

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

 

时间: 2024-08-04 03:17:33

REDIM陷阱(很多人都看过了吧)的相关文章

很多人都在埋怨没有遇到好的团队,但好的团队不可能凭空出现,一流的团队不能仅靠团队成员努力,作为Leader,要有可行的规划,并坚定地执行、时势地调整(转)

  <西游记>中的唐僧团队历经千难万险,终于求得真经,目标明确.分工合理为这支队伍最终走向成功奠定了基础.唐僧从一开始,就为这个团队设定了西天取经的目标,虽然经历各种挫折与磨难,但目标从未动摇.悟空探路.八戒牵马.沙僧挑担,几位徒弟一起肩负着保护唐僧的任务.虽然性格迥异.各有缺点,但目标分解合理及成员分工合作,最终风雨同舟,取得真经. <西游记>的故事引申到实际团队技术管理中,也一样有借鉴意义,本文作者为CTO俱乐部会员.湖北同城一家网络科技有限公司开发总监杨斌,他结合自己多年经历

很多人都只是使用iPhone上的功能只发挥到千元机类的的级别

自从iPhone问世以来,网上就流传一句话,很多人都只是使用iPhone上的功能只发挥到千元机类的的级别,这意味着iPhone上还存在很多需要我们去挖掘的功能.最近,外媒就整理了12个鲜为人知的iPhone使用技巧,来了解一下,看你使用上了几个.在打开飞行模式后,iPhone的充电速度会比平时更快.而且在最新的iOS7操作系统中,用户打开飞行模式的方法也非常简单,我们需要做的就是从屏幕下方向上滑动打开控制中心,然后点击飞行模式的图标即可.双击iPhone Home键可以查看最近的应用使用记录,之

最近接触了一些微商和创业人士,很多人都在抱怨

最近接触了一些微商和创业人士,很多人都在抱怨,为什么都说微信是风口,自己却飞不起来. 很多微商代理压了很多货,却发现根本卖不动,2014年,一些微商赚到了钱,但更多的微商,尤其是微商代理却陷入困境,苦苦支撑,以前刷朋友圈广告还能卖出一些,现在不仅卖不出去货,还发现自己发的广告没有赞.没有评论,原来自己早已经被屏蔽了,有几千好友,都是僵尸. 你需要思考的核心问题是:你的努力方向对吗?从小,我们受到的教育就是努力.刻苦,但是现在努力.刻苦也可能是贬义词.如果你的努力和刻苦用错了方向,那距离成功的目标

很多人都为品牌在社会化媒体上进行传播的实效性存疑

长久以来,很多人都为品牌在社会化媒体上进行传播的实效性存疑.企业主或品牌方在一开始对转评量.粉丝数等数据的疯狂热衷到之后理性看待,这一转变也正好反应了品牌方对社会化营销的认知过程.但是,似乎到目前为止,大多数marketing仍然对动辄数十万粉丝的变现和价值证明感到无力.于是,各种看似牛逼的创意似乎便成为了实效问题的遮羞布-.好在,技术发展日新月异.微信.微博等社会化媒体平台先驱已经能很好的解决支付的便捷性,marketing似乎翻身有望. 那么,如何理解社会化电商呢? 1.社会化电商是去中心化

很多人都收到过类似的垃圾短信

"好消息,临港新城上海地铁延伸现房,多户型清盘均价仅4990"--可能很多人都收到过类似的垃圾短信.而针对这种不时扰民的商业推销短信,上海将从12月1日起推行"一键退订"手段,以此遏制各类垃圾短信. 据上海市通信管理局介绍,一些房产推销.办班培训等机构通过本地106×××××行业短信端口发送商业短信,上海移动.电信. 联通 手机用户今后收到这类短信,只需要回复"0000",就可以拒收本地端口号码发出的短信.这一"一键退订"将对

相信很多人都已经完成了自己的13年终总结和14年新年规划

2013年已成为过去式,相信很多人都已经完成了自己的13年终总结和14年新年规划.那么,也是时候对整个广告营销行业的13年进行总结和对14年进行新一年展望讨论了. 第七届21世纪国际广告国际峰会将于2014年2月26日至28日在青岛召开,您听说了吗? 21世纪广告国际峰会一直致力于加强中国广告营销企业间的合作,搭建人脉的桥梁,共创行业联盟.为广告营销行业的大繁荣.大发展起到积极作用.历经七年淬炼,21世纪广告国际峰会已经成为了广告营销行业的品牌论坛组织. 本届峰会中,峰会理事会将正式成立并召开第

做程序员工资高福利好?其实是压力山大 很多人都快疯了

中介交易 SEO诊断淘宝客 站长团购 云主机 技术大厅 软件程序员在如今看来是一个既能挣钱又有工作保障的职业,但是,这种职业对你的精神健康却会造成巨大的伤害. 有两种事情几乎能让程序员疯掉. 一个是被人们称作"骗子综合征(imposter syndrome)"的东西.患这种症状的人通常是发现一起共事的所有程序员都比自己聪明.比自己有天份.比自己有才能.你生活中一直恐惧中,担心其他人会最终发现你是个冒牌货.你的技术和能力是装出来的. 经常会有女性程序员坦白说遭受"骗子综合征(i

做程序员压力山大,很多人都快疯了

软件程序员在如今看来是一个既能挣钱又有工作保障的职业,但是,这种职业对你的精神健康却会造成巨大的伤害. 有两种事情几乎能让程序员疯掉. 一个是被人们称作"骗子综合征(imposter syndrome)"的东西.患这种症状的人通常是发现一起共事的所有程序员都比自己聪明.比自己有天份.比自己有才能.你生活中一直恐惧中,担心其他人会最终发现你是个冒牌货.你的技术和能力是装出来的. 经常会有女性程序员坦白说遭受"骗子综合征(imposter syndrome)"的折磨,这

无意中的发现 网上code很多人都没考虑到的 彻底禁锢Ctrl+Alt+Del

问题描述 按下Ctrl+Alt+Delete后不让弹出这个Windows安全对话框C#WinForm中,要求:按下Ctrl+Alt+Del不再弹出"Windows安全"对话框因为我已经在程序中将Ctrl+Alt+Delete这个组合键屏蔽掉了原来是没什么问题的任务管理器是不会出来的可现在我在"控制面板"->"用户帐户"->"更改用户登录或注销的方式"里面选择了传统的登录模式后再执行我的程序发现按下Ctrl+Alt+