第2次做業

做業地址:【https://edu.cnblogs.com/campus/nenu/2016CS/homework/2139php

1、效能分析html

要求0:項目地址 https://git.coding.net/Jingr98/wfAnalysis.git前端

要求1:vue

1.以war_and_peace.txt做爲測試文件,原程序連續三次運行的消耗時間以下:java

(1)第一次:150.474snode

(2)第二次:151.516sgit

(3)第三次:164.399sweb

2.猜想程序瓶頸:編程

(1)bufferedReader.readLine()從文本文件中按行讀取字符串,並依次存入字符串words中。小程序

while((lineword=bufferedReader.readLine())!=null) { words+=lineword+"\n"; }

猜想緣由:使用BufferedReader緩存流,readLine方法讀取一行文本。由於文本文件很大,程序按行讀取到全部內容所耗費的時間應該較多,因此此處應該爲程序的一個瓶頸。若是優化後的程序能夠減小讀取文件的次數,即換一種讀文件的方式,那麼程序運行耗時應該會減小。

(2)分割字符串words並存入數組中。

String[] word = str.split("[^a-zA-Z0-9]|\\s");

猜想緣由:分割字符串並獲得一個個的單詞,感受程序在這裏的工做確定很多,相對耗時也較長。可是優化後的程序在這裏應該不會有什麼改進,由於這是程序處理字符串必不可少的工做,沒辦法簡化了...

(3)for語句依次處理單詞數組word[ ]中的每個元素(先調用isLegal(word[i])判斷單詞是否合法,若合法再判斷word[i]是否已經是myMap的鍵)。

Map<String,Integer> myMap = new TreeMap<String,Integer>(); //遍歷數組將其存入Map<String,Integer>中 int wordLen = word.length; for(int i=0;i<wordLen;i++) { //首先判斷是否爲合法單詞  if(isLegal(word[i])) { if(myMap.containsKey(word[i])) { num = myMap.get(word[i]); myMap.put(word[i], num+1); } else { myMap.put(word[i], 1); } } } 

猜想緣由:單詞不少,因此各類判斷語句執行的次數也不少。而且每次執行的不是簡單的判斷語句,要麼是調用本身定義的函數isLegal(),要麼就是調用map對象下的方法containsKey(),這些應該是很耗時的。若是優化後的程序能夠較少函數的調用次數或者減小判斷語句的執行,應該會提升性能。

要求2:

利用Java VisualVM工具對程序進行效能分析以下:

對profile的結果進行分析找出了程序運行中最花費時間的3個函數(或代碼片斷),以下:

1.耗時最長的部分是調用java.lang.StringBuilder

源於如下代碼片斷:

while((lineword=bufferedReader.readLine())!=null) { words+=lineword+"\n"; }

(1)瓶頸分析:使用「+」號進行字符串拼接的效率很是低。我用了一個簡單的小例子以下,來查看編譯器是怎麼處理 + 操做符的。

String str0 = "a"; String str1 = str0 + "b";

下面是該程序片斷編譯後的字節碼指令:

public static void main(java.lang.String[]); Code: 0: ldc #2 // String a 2: astore_1 3: new #3 // class java/lang/StringBuilder 6: dup 7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 10: aload_1 11: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14: ldc #6 // String b 16: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 22: astore_2 23: return }

經過分析這段字節碼,發現「+」拼接操做實際上被編譯器理解成了這個樣子:

String str0 = "a"; StringBuilder sb = new StringBuilder(); sb.append(str0).append("b"); String str1 = sb.toString();

發現中間多出來了一個StringBuilder對象,即在編譯的過程 "+" 被編譯成了StringBuilder對象進行操做,而且拼接幾回就會建立幾個StringBuilder臨時對象。很顯然,在該while循環體中每讀取一行文本「+」到字符串words後面時就會建立一個對象,使用「+」號讀取完畢後建立了多個StringBuilder對象,執行完以後還要進行回收,無疑大大下降了效率。

(2)解決方法:能夠在循環體外直接建立一個BufferedReader對象,而後在循環體中經過append方法拼接字符串,這樣就省下了建立並回收不少個臨時對象的消耗。(在須要拼接大量字符串時,仍是使用StringBuilder/BufferedReader對象爲好)

2.其次是isLegal()函數耗時較長

(1)瓶頸分析:處理word[ ]數組中每一個元素時都調用自定義的isLegal()函數,而且每次調用時都會建立String、Pattern、Matcher變量。

(2)解決辦法:將isLegal()函數併入到countNum()函數裏,即減小調用關係樹。在for語句以前建立一個String變量和一個Patten變量供數組中全部元素使用,在for語句內部每次調用p.matcher(word[i]).matches()判斷元素是否爲合法單詞。

3.對TreeMap對象的操做耗時較長

 

(1)瓶頸分析:TreeMap內部是按照鍵值對有必定的順序,在對其操做(插入或刪除)時,由於須要維護內部的平衡,因此會犧牲一些效率。

(2)解決辦法:將TreeMap對象換成HashMap對象,能夠實現對Map的快速操做。由於Hash Map裏鍵值對的排序是隨機的,因此這樣改的話雖能夠提升效率,但卻失去了其順序性,還需本身排序。

要求3:

優化後的程序效能分析以下:

(每次profile的結果都有些不一樣,下圖僅爲第一次分析結果)

1.改進後的3個函數此時的耗時

(1)用StringBuffer拼接字符串

(2)去掉isLegal函數,在countNum函數內部添加等價代碼以下

String regex="^[a-zA-Z][a-zA-Z0-9]*$"; Pattern p = Pattern.compile(regex); for(int i=0;i<wordLen;i++) { //首先判斷是否爲合法單詞 if(p.matcher(word[i]).matches()) { if(myMap.containsKey(word[i])) { num = myMap.get(word[i]); myMap.put(word[i], num+1); } else { myMap.put(word[i], 1); } } }

耗時以下:

(3)換用HashMap耗時以下:

2.程序優化後連續三次運行的消耗時間以下:

(1)第一次:1.553s

(2)第二次:1.162s

(3)第三次:1.174s

2、自我評估

       做爲一名計算機科學與技術專業的大三學生,目前爲止,我學過計算機導論、計算機組成原理、操做系統、編譯原理等計算機專業的基礎課程,雖然說不上本身對所學知識掌握的多好,但也算是有個大概的瞭解,有必定的理論知識基礎。同時,我也上完了多種編程語言課程,例如C語言/C++、Java、Python、php、html等。雖然在課堂上已經接觸到了這麼多的編程語言,可是我感受本身學的都很膚淺,語法掌握的不牢、只能參考別人的代碼編一些小程序,有時候都很差意思說本身學過。在實戰編程方面,惟一以爲本身作的不錯的地方就是用HTML+CSS+Javascript寫web前端了。由於在大一暑假加入了學校的卓音工做室,因此有機會能夠參與學校相關網站的開發與維護工做。在這個過程當中,我收穫了不少,一是提高了本身的學習能力,由於前端技術更新迭代很快,可能這個項目中用node.js,下一個項目中就換成了vue.js,因此須要我去不斷學習;二是具有了團隊協做能力,任何項目的完成都離不開團隊協做,每一次的協做經驗都會指導我下次如何改進;三是擁有了良好的自我管理能力,由於要平衡好學習任務和項目任務,因此本身要提升作事效率,自我激勵、開心過好每一天!

        離成爲一個合格的 IT專業畢業生,真的還差好多。首先我須要掌握一種編程語言(C語言或者Java),能夠熟練編寫程序解決問題;其次我須要鍛鍊本身的邏輯思惟能力,由於IT行業不少是工程思想,須要從業者具備較高的邏輯思惟能力,尤爲是研發人員,本身在這方面是很欠缺的;而後若是本身之後想要成爲一名前端工程師,不只須要去了解前端工程化、後臺技術方面、網絡技術等相關知識,還要掌握一門後端語言,這樣才能更好的寫好web前端代碼,畢竟web網頁最終仍是要與後端語言進行結合造成一個真正的動態網站。

Skills/技能 課前評估(0-9) 課後評估(0-9)
Programming Overall/對編程總體的理解  3  5
programming:Comprehension
(程序理解)(如何理解已有的程序,經過閱讀、分析、debug)
 3  6
Programming:Implementation(模塊實現,逐步細化)  1  4
Programming:Code Review/Code Quality(代碼複審/規範/質量)  3  5
Programming:BigData(處理大數據)  0  3
Programming Language(C)  3  6
Ability to Learn:自主學習的能力  3  6
相關文章
相關標籤/搜索