PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 20 | 20 |
Estimate | 估計這個任務須要多少時間 | 400 | 600 |
Development | 開發 | 520 | 665 |
Analysis | 需求分析 (包括學習新技術) | 30 | 30 |
Design Spec | 生成設計文檔 | 20 | 20 |
Design Review | 設計複審 | 20 | 25 |
Coding Standard | 代碼規範 (爲目前的開發制定合適的規範) | 20 | 20 |
Design | 具體設計 | 20 | 35 |
Coding | 具體編碼 | 300 | 400 |
Code Review | 代碼複審 | 20 | 20 |
Test | 測試(自我測試,修改代碼,提交修改) | 630 | 650 |
Reporting | 報告 | 20 | 30 |
Test Report | 測試報告 | 10 | 10 |
Size Measurement | 計算工做量 | 10 | 15 |
Postmortem & Process Improvement Plan | 過後總結, 並提出過程改進計劃 | 20 | 10 |
合計 | 1140 | 1285 |
前期討論的時候咱們將代碼功能分爲7塊,包括:文件導入、單詞分割、統計字符數、統計單詞數量、行數統計、統計單詞詞頻、結果寫入文件。原定每一個功能一個函數,可是通過後期具體編程以及反覆考慮以後決定將功能劃分爲5大塊:主函數導入文件、字符統計、單詞數量統計以及詞頻統計、行數統計、結果輸出。主函數main導入文件後產生一個ifstream對象,經過調用charCount(ifstream,...)字符統計函數、lineCount(ifstream)行數統計、wordCount(...)單詞數量統計以及詞頻統計函數,printResult(...)結果輸出函數實現所需功能。
代碼總體流程爲先讀取文件,讀取過程當中先將特殊符號替換成空格「 」,同時每讀取一個字符就對字符數進行統計,讀取的數據存儲到vector容器中。單詞的數量統計以及詞頻統計的流程是將vector中的字符轉換爲小寫後讀入到string中,在對string進行用空格分割,分割後獲得的每一個單詞存入vector<string>容器中,再對獲得的單詞進行合法性篩選,過濾掉不符合單詞定義的單詞。過濾完成以後,開始遍歷每一個單詞,並將單詞和出現次數分別做爲map的鍵和值存儲,而後經過vector過渡使用sort函數進行詞頻由高到低、單詞按字典排序。一切統計完成後將組織結果輸出到result.txt文件中。
排序部分是比較關鍵的部分,上面提到用map存儲單詞及其出現次數,這裏詳細說明如何排序。先把map中的數據放到vector中:
vector
再利用sort()函數排序:
sort(wordSort.begin(), wordSort.end(), CmpByValue());
CmpByValue結構體中定義次數由大到小和單詞按字母表排序:
struct CmpByValue { bool operator()(const PAIR& lhs, const PAIR& rhs) { if (lhs.second != rhs.second) { return lhs.second > rhs.second; } else { return lhs.first < rhs.first; } } };
用例測試:
---git
從google scholar上下載了10篇cvpr/iccv文章,組成十個測試用例對代碼進行測試,結果以下:
測試樣例:
論文樣例:
測試過程:
測試結果:
github
功能測試 | 測試狀況 | 解決狀況 |
---|---|---|
主函數導入文件 | 導入文件正常 | |
字符統計 | 字符統計正常 | |
單詞數量統計以及詞頻統計 | 容器溢出 | 已解決 |
行數統計 | 行數統計正常 | |
結果輸出 | 單詞排序有亂序 | 已解決 |
展現性能分析圖和程序中消耗最大的函數編程
通過性能分析後發現wordCount函數中使用CPU較多:
數組
通過觀察,該函數使用大量的字符數組存儲,相應地也使用了較多的循環去處理,查看性能分析中佔用最多的部分發現是單詞過濾部分的二重循環中其中的一個二維數組將字母轉換成小寫的模塊,因而變換存儲結構,將wordCount函數中的二維數組換成string或者vector,再將小寫的轉換移到vector轉存string是同步進行,並簡化沒必要要的二重循環以後再進行性能分析。優化前wordCount函數的瓶頸段:
函數
優化以後的CPU使用狀況以下圖所示:
性能
此時的瓶頸段以下:學習
優化共計使用了10小時,不單單是WordCount函數作了優化,程序的多個地方也作了細小的優化,讓代碼更有效率。
測試
字符統計函數部分代碼:讀取過程當中先將特殊符號替換成空格「 」,同時每讀取一個字符就對字符數進行統計,讀取的數據存儲到vector容器中。優化
單詞數量統計以及詞頻統計函數部分代碼:將vector中的字符轉換爲小寫後讀入到string中,在對string進行用空格分割,分割後獲得的每一個單詞存入vector
過濾完成以後,開始遍歷每一個單詞,並將單詞和出現次數分別做爲map的鍵和值存儲,而後經過vector過渡使用sort函數進行詞頻由高到低、單詞按字典排序。
在編寫WordCount函數體時沒有選好存儲結構,使用了動態二維數組,致使經常一不當心就越界,報錯;經過和隊友討論以及上網查找資料研究以後決定使用string和vector進行存儲,這樣能夠很大程度上節省了維護下標的繁重任務。
個人隊友是一個很是認真細心的人,她的代碼很規範,代碼風格很好,有很好的閱讀體驗。並且編程邏輯很嚴密,這點是我要向她學習的地方。