巧用頭腦思考,提高軟體運行效率-淺談程式演算法

來源:互聯網
上載者:User
程式|演算法 關於VC# 如何提高運行效率

大家都知道.NET 讓我們開發程式更加的簡單,特別是對與企業性的大型軟體的開發,它和JAVA一樣運用了GC(記憶體回收) 的機制,有了記憶體回收就可以丟掉在C或C++ 中痛苦的指標, 可以不用花心思去關注記憶體是不是已經釋放,可以說給程式員減輕了負擔。

我在這不說關於GC是不是好,GC也有它自己的缺點,如已經不必要用的記憶體不會提前釋放,或多或少的浪費了記憶體,我不想說C#中採用GC 有多成功,但是從我自己開發的經曆來,C#的效率很讓人失望,同一功能用C++ 實現比C#實現更節約記憶體,我沒有用C#開發過大的程式,不知道究竟C#對記憶體的要求有多大,按照我的一程式分析, 有記憶體回收的機制的語言是C++ 的記憶體的3-20倍,怎麼樣才能提高C#開發的程式的運行效率,怎麼才可以節約空間呢?

縱所周知,演算法是程式的核心,我們無法改變語言自己本身特有的,只有從我們演算法來著手來想辦法!同樣的能夠可以用不同的思路來實現,所謂條條大路同羅馬,大家都知道,也許我們所缺少的是思考,我們作為程式員 本來就做思考的活動,能為一個問題思考可以說是一件樂事!

下面我說一個例子,關於VC#的使用,對於同一個問題可以使用不同的方法

我們現在面臨的問題如下(假設)
要用TreeView 做一個類似資源總管的東西

說到演算法很簡單:就是遍曆電腦裡的檔案,並且添加到TreeView 接點中!

一種最簡單的(核心)代碼如下:

private void button1_Click(object sender, System.EventArgs e)
{
try
{
DirectoryInfo ainfo=new DirectoryInfo("C:\\");
TreeNode nan=new TreeNode(ainfo.FullName);
this.treeView1.Nodes.Add(nan);
addNode(nan);
}
catch(System.IO.DirectoryNotFoundException eDnfa)
{
MessageBox.Show(eDnfa.Message);

}
}

private void addNode(TreeNode tn)
{

DirectoryInfo di=new DirectoryInfo(tn.Text);
DirectoryInfo[] aTemp=di.GetDirectories();
if (aTemp.Length>0)
foreach(DirectoryInfo d in aTemp)
{
TreeNode node=new TreeNode(d.FullName);
tn.Nodes.Add(node);
addNode(node);

}
FileInfo[] sFiles=di.GetFiles();
foreach(FileInfo f in sFiles )
{
TreeNode node=new TreeNode(f.FullName);
tn.Nodes.Add(node);
}

}


上面的代碼顯示C盤的全部檔案是TREEVIEW中,大家可以分析它執行的先後順序:




button1 的 Click 引發後執行後面的操作,然後調用addNode(TreeNode tn) 方法!仔細看裡面,其實用到了遞迴, 首先是 把“C:\\” 加入到根接點,然後訪問C盤第一個檔案夾,加入到樹中,然後訪問C盤第一個檔案夾下的第一個檔案夾,加入到數中,以次遞迴,當到了盡頭,然後再返回加第而個檔案,形象的說是做S形迴圈! 我無法用圖來說明具體情況,也許比較難理解,我想只要自己仔細思考是可以想出來,我們要永遠記住,程式員這一個職業就是 思考的 職業! 還要創新!

毫無疑問,上面的演算法是正確的,但是到最後使用了多少記憶體呢,全部的接點都加到了Treeview 中,無疑這樣使用了很多空間! 更鬱悶的是如果我們要操作軟體,必須等軟體已經做完上一部分的事才響應我們接下來來操作, 上面的方法會導致我們的軟體有 死機現象 有沒有更好的辦法?


問題就出現我們使用了常規的想法,就差一點自己的改動!

我們仔細想一想,在TreeView中,我們想要看見(這裡指的看見是指人眼可以看他在樹中)所有接點需要我們用滑鼠去展開,當我們沒有展開接點呢(沒有展開接點前有必要就加到樹中嗎)? 上面的演算法是一次性的初始化了全部了的接點,只要我們不一次性初始化就可以了!

看下面的方法:

private void Form1_Load(object sender, System.EventArgs e)
{
this.treeView1 .Nodes .Clear ();
DirectoryInfo my=new DirectoryInfo ("c:\\");
TreeNode nan=new TreeNode(@my.FullName);
this.treeView1.Nodes.Add(nan);
addMyTreeView(nan);



}

private void addMyTreeView(TreeNode mNode)
{


try
{
DirectoryInfo di=new DirectoryInfo(@mNode.Text);
DirectoryInfo[] aTemp=di.GetDirectories();
for(int i=0;i<aTemp.Length ;i++)
{
TreeNode my2=new TreeNode (@aTemp[i].FullName );
mNode.Nodes .Add(my2);
//addMyTreeView(my2); this is a bad method!
DirectoryInfo di2=new DirectoryInfo(@my2.Text );
DirectoryInfo[] aTemp2=di2.GetDirectories();
for(int j=0;j<aTemp2.Length ;j++)
{
TreeNode my3=new TreeNode (@aTemp2[j].FullName );
my2.Nodes .Add (my3);
}


}
}
catch(Exception ex)
{

}

}

private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
{

e.Node.Nodes.Clear();
this.addMyTreeView(e.Node);



}

private void treeView1_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
{
e.Node.Nodes.Clear();
this.addMyTreeView(e.Node);

}

上面的是我們充分的運用了treeView控制項的所有方法 上面的思路如下:
在表單Load的 加入“c:\\” 接點,然後調用 private void addMyTreeView(TreeNode mNode),但是在這裡面用了兩層迴圈,也就 把 相對於C 盤的 檔案加入了兩層,(C盤的檔案我們可以看成是一級一級的目錄), 當 AfterSelect 發生時 這次調用 addMyTreeView(TreeNode mNode) ,當BeforeExpand 時清除 接點 仔細比較第種演算法,我們可以看出第二種比第一種更方便,第二種也沒有增加什麼技術難度,只是 換了一了下思維方式!



你也許會說我第一種方法是有意浪費空間的,當然我只是為做一個有對比的示範,我相信大家還可以在我第二中方法上更加最佳化!


軟體開發不是簡單的複製和粘貼,更加要思考, 不要輕視小程式的資源問題,也許在對大程式時就可以節約不必要的空間時間浪費!

今天就寫到這了!


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.