小談最佳化和架構理念

來源:互聯網
上載者:User

今天碰到兩個問題,總結一下,最近碰到的知識很多,但總不夠時間來掌握這些東西,例如設計模式裡面的模式redo/undo和資料redo/undo。還有儲存一個文檔的記憶體資料結構,磁碟上的檔案格式,表格計算方法,AVM2的內部運行情況。設計模式上,演算法上的,工具應用上的,都有很多需要去一點點掌握。先入下正題,分別兩個問題。

 

 

一:老一輩說過的話,演算法上的最佳化還不如架構上的,系統上的最佳化。今天我就赤裸裸地遇到這個問題。

 

問題描述:

做的是一個代碼查看協助工具輔助裡面的繪製所有類,介面繼承布局,當兩個樹根A,B要並排放置的時候,是要注意到A這顆樹的寬度,而進入A這顆樹,其中也有子樹與子樹之間的寬度測量,這樣也就類似於檔案系統裡面統計一個檔案夾的磁碟容量問題。顯然用深搜遞迴是可以簡單搞定。於是乎寫出了下面的代碼 

 

/**<br /> * DFS to classes inherit tree<br /> * @param ve<br /> * @return<br /> *<br /> */<br />private function _DFSClassInherit(ve: IViewElement): int<br />{<br />if (!ICIClass(ve).childs)<br />{<br />ICIViewElement(ve).treeBottom += ve.myY;<br />return ICIViewElement(ve).rootWidth;<br />}</p><p>var totalWidth: int = 0;<br />var totalHeight: int = 0;<br />var beginX: int = ve.myX - 100;<br />var beginY: int = ve.myY + 100;<br />var chl: Vector.<ICIClass> = ICIClass(ve).childs;</p><p>for each (var cla: ICIClass in chl)<br />{<br />cla.myX = beginX + totalWidth;<br />cla.myY = beginY;<br />cla.myVisible = true;<br />cla.refresh();<br />totalWidth += _DFSClassInherit(cla) + 50;<br />totalHeight = (totalHeight > cla.treeBottom) ? totalHeight : cla.treeBottom;<br />}</p><p>ve.refreshRelationLines();<br />ICIViewElement(ve).rootWidth = totalWidth;<br />ICIViewElement(ve).treeBottom = totalHeight;</p><p>return totalWidth;<br />}

 

 耗時8546MS.考慮最佳化,初步懷疑是AS3處理遞迴慢,所以用棧來實現,在寫的時候也懷疑了如果不是遞迴的事呢?但還是把代碼寫了再說,又出現了以下代碼。

 

/**<br /> * DFS by stack caculate each floor width<br /> * @param ve<br /> * @return<br /> *<br /> */<br />private function _DFSClassInherit(ve: IViewElement): int<br />{<br />var stack: Vector.<IViewElement> = new Vector.<IViewElement>();<br />var map: Array = new Array();<br />var begin: int = 0;</p><p>stack.push(ve);<br />var starTime: int = getTimer();<br />while (begin != stack.length)<br />{<br />var chl: Vector.<ICIClass> = ICIClass(stack[begin]).childs;<br />if (!chl)<br />{<br />begin++;<br />continue;<br />}</p><p>for each (var cls: ICIClass in chl)<br />{<br />stack.push(cls);<br />map[stack.length - 1] = begin;<br />}</p><p>begin++;<br />}</p><p>var size: int = stack.length;<br />for (var i: int = size-1; i >= 1; --i)<br />{<br />var tmp: IViewElement = stack[map[i]];<br />ICIClass(tmp).rootWidth += ICIClass(stack[i]).rootWidth + 50;<br />}</p><p>return CE.Result_S_OK;<br />}</p><p>/**<br /> * BFS<br /> * @param ve<br /> * @return<br /> */<br />private function _BFSClassInherit(ve: IViewElement): int<br />{<br />var queue: Vector.<IViewElement> = new Vector.<IViewElement>();<br />var begin: int = 0;<br />var maxHeight: int = 0;</p><p>queue.push(ve);</p><p>while (begin != queue.length)<br />{<br />var tmp: IViewElement = queue[begin];<br />var chl: Vector.<ICIClass> = ICIClass(tmp).childs;<br />var totalWidth: int = 0;<br />var beginX: int = tmp.myX - 100;<br />var beginY: int = tmp.myY + tmp.myHeight;</p><p>for each (var cla: ICIClass in chl)<br />{<br />cla.myY = beginY + 50;<br />cla.myX = beginX + totalWidth;<br />cla.myVisible = true;<br />cla.refresh();<br />totalWidth += cla.rootWidth + 50;<br />maxHeight = (maxHeight > (cla.myY + cla.myHeight + 50)) ? maxHeight : (cla.myY + cla.myHeight + 50);<br />queue.push(cla);<br />}<br />tmp.refreshRelationLines();<br />begin++;<br />}</p><p>return maxHeight;<br />}

 

用棧實現深搜,統計樹寬,然後再廣搜去布局。以為這樣會有一個比較完美的結局,但是耗時7345MS。不是遞迴出錯。直接往程式挖塊來分析,結果得出如下結果:

 

the root is *****************DomDefaultAccepter<br />first++++++one++++parth 647<br />first++++++two+++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first++++++one++++parth 0<br />first.... 648<br />second.... 0<br />DFS 648<br />BFS 345

在第一個語句塊耗時,跳進去分析得出下面幾個語句,頓時陷入深思

 

if (!CT.has_CIClass(_childs, cls))<br />{<br />cldV = ICIView(_view).createViewElementByDataElement(cls) as ICIClass;<br />_childs.push(cldV);<br />cldV.setParent(this);<br />}

 

三條語句還只是迷宮的開始,下面還有若干個拐彎,於是乎效率就降下來了。呼叫華哥問之,答曰“正常”。。。。又繼續陷入深思。。

 

以前考慮的是演算法的最佳化,按秒按常數來最佳化,但是這些到了現實中,還不如一個架構的最佳化來的強大。又讓我想到,在一個簡單的CPP檔案中,瓶頸的可能就是那些常數或者儲存結構,或者演算法有問題。但是到了多個CPP檔案構成的一個工程,瓶頸的就是如何組織這些CPP的方法上了,所以就有了設計模式,有了架構思想這些,從狹義上講,這些也許算是一種架構演算法吧。無怪乎有人說了,演算法和設計模式才是最重要的,語言不過就是工具而已。昨晚看了下COM的思想,比較於現在的介面編程,倍感豁然開朗,不從一個側面去看C++,還真看不清裡面的編程思想,跳出來後再往回看,確實又是那麼一回事,神奇,神奇。

 

二,另一個問題是,為了實現一種架構概念,而破壞一個適合該架構的演算法模型,去思考另一種方法計算,是否可取?

一個顯示元素,即類,介面或者包,這麼一個元素,具有的行為應該是怎樣的?這個是應該思考和選取的,具有refresh(),refreshrelationline(),那麼如果是儲存和這個元素有關的所有親戚類和介面呢?例如我要使這個元素的所有親戚類和介面全部隱藏,(子類的子類,實現介面的子介面,父介面這些),這個行為或許就不應該在這個元素裡面,究竟應不應該呢?借鑒於面有個hitLogic的類,按理應該不屬於這個元素的行為,好,暫時不從這個類行為來考慮這個,從實現這個遍曆其親戚元素這個角度出發,就很應該放在這個元素裡面,每個元素只儲存和該元素最直接親戚元素,這樣

 

 for each (tmp in childs)<br />{<br />if (tmp.myVisible)<br />{<br />ve.myVisible = false;<br />tmp.closeTree();<br />}<br />}

這樣通過置換不同親戚而層層跳下去,正如在遍曆一棵樹一樣。例如程式結構天然地形成一個遞迴結構。但是如果把這個closeTree()硬拿到外面的檔案來,會增加記憶體控制難度,所有親戚節點全部存在一塊記憶體中,而且還有一種情況不能控制的是,對於一個已經展開的3層的類結構下,關閉第二層的子類,然後再關閉第一層,再開啟第一層,此時應該出現的只是第一和第二層,但是用外面這個檔案的函數來實現的話,不加控制,難以實現。

 

所以,在這個軟體架構實現一種概念的時候,是以什麼為標準的?是以效率,還是純粹類比自然現象?還是純粹實現一個概念?為了實現一個架構的概念,往往實現一個功能要兜很大的一個圈,這樣子是否符合常規?探索中。。。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.