第4周小組做業:WordCount優化

第4周小組做業:WordCount優化

1、基本任務:代碼編寫+單元測試

小組github 地址 

https://github.com/iwannastay/WcPro/tree/stage3/stage3 git


 

PSP表格

PSP2.1 PSP階段 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 30 60
Estimate 估計任務須要多少時間 30 60
Development 開發 180 240
Analysis 需求分析 20 30
Design Spec 生成設計文檔 20 30
Design Review 設計複審 20 30
Coding Standard 代碼規範 30 10
Design 具體設計 30 50
Coding 具體編碼 30 40
Code Review 代碼複審 30 40
Test 測試 50 10
Reporting 報告 70 240
Test Report 測試報告 30 100
Size Measurement 計算工做量 20 60
Postmortem 總結 20 80
  合計 340 540

接口設計

  • 接口描述

    我負責的模塊是單詞排序,即由外部傳入各單詞詞頻,模塊將其排序並輸出。github

  • 設計思路

    因爲是數目未知的數值元素,故能夠將輸入輸出接口定義爲vector<int>數組;數組的排序能夠選擇多種算法如插入排序、合併排序、基數排序、桶排序、快速排序等,因爲處理的文本可能極大,對算法性能要求較高,故此選擇隨機快排實現該接口;然而本程序包含額外的條件——1.單詞詞頻同步輸出,2.同頻的單詞按照字母順序排列,故不能僅用單詞的詞頻做爲接口,而需將單詞自己的索引輸入,因爲外部數據結構未知,故直接引用單詞自己做爲參數,即便用vector<pair<string,int>>做爲模塊外部接口。算法

  • 實現過程

    因爲外部存儲結構使用map<pair<string,int>>,且map的實現機制是紅黑樹的平衡二叉樹,不支持索引操做,爲了便於排序,需進行map->vector的轉換。編程

//詞頻排序
void WcFile::RankProcess()
{
    int count = 0, size = Word_List.size();
    map<string, int>::iterator iter = Word_List.begin();
    while (iter != Word_List.end())
    {
        Rank_List.push_back(*iter);
        iter++;
    }
    //隨機快排
    Random_Quick_Sort(Rank_List, 0, Rank_List.size() - 1);
}

 

    排序算法實現數組

 

//快速排序分劃程序
int WcFile::Partition(vector<pair<string, int>> &A, int p, int q)
{
    auto x = A[p];
    int i = p;
    for (int j = p + 1; j <= q; j++)
    {
        if (ComparePriority(A[j],x))
        {
            i = i + 1;
            Swap(A[i], A[j]);
        }
    }
    Swap(A[p], A[i]);
    return i;
}

//隨機化快速排序分劃程序
int WcFile::Random_Partition(vector<pair<string, int>> &A, int p, int q)
{
    int i = rand() % (q - p) + p;
    Swap(A[i], A[p]);
    return Partition(A, p, q);
}

//隨機化快速排序
void WcFile::Random_Quick_Sort(vector<pair<string, int>> &A, int p, int q)
{
    if (p < q)
    {
        int i = Random_Partition(A, p, q);
        Random_Quick_Sort(A, p, i - 1);
        Random_Quick_Sort(A, i + 1, q);
    }
}

//交換元素
void WcFile::Swap(pair<string, int> &m, pair<string, int> &n)
{
    pair<string, int> tmp;
    tmp = m;
    m = n;
    n = tmp;
}

//首字母排序
bool WcFile::ComparePriority(pair<string, int> &m, pair<string, int> &n)
{
    if (m.second != n.second)
        return m.second > n.second ? true : false;
    else
        return m.first < n.first ? true : false;
}

 


測試設計

  保證設計的測試用例應至少覆蓋函數中全部的可執行語句,同時主要空數組、最差狀況、詞頻排序、字母排序、二者混合等各類狀況設計測試用例。數據結構

 


單元測試

試用測試腳本進行單元測試,過程以下:框架

單元測試效果較好,測試結果均正確,且排序性能較高。dom


 

小組貢獻

  咱們小組齊心合力,共克難關,積極討論並指出其餘組員的問題,最終得出個人小組貢獻分爲0.3。函數

 

2、擴展任務:靜態測試

1.代碼規範

  我選擇了代碼風格規範中:斷行與空白的{}行、分行、命名、下劃線、大小寫;工具

      代碼設計規範中:函數、gogo、錯誤處理、斷言(在其餘大型程序中經常使用,在本次做業中未使用)、析構函數、new和delete、類型繼承。

  個人編程習慣與以上附錄中所述規範大體相同,少量部分持不一樣意見。而在其餘如代碼審查等重要規範上有待提升。


 

2.同組分析

  我分析了組員17027的代碼,縮進、斷行風格整潔,命名簡單明瞭,邏輯清晰易讀,較好地遵照了設計規範。

//導入文件
bool WcFile::LoadFile(const char *_filename)
{
    File_Name = _filename;
    File_Stream.open(File_Name);
    if (!File_Stream)
    {
        cout << "Fail to open the source file:" << File_Name << endl;
        system("exit");
    }
    return true;
}

//保存結果
void WcFile::SaveResult()
{
    File_Stream.close();
    File_Stream.open(ResultFile_Name);
    if (!File_Stream)
    {
        cout << "Fail to open the result file." << endl;
        system("exit");
    }

    for (int i = 0; i < 100 && i < Rank_List.size(); i++)
        File_Stream << Rank_List[i].first << "\t" << Rank_List[i].second << endl;
    File_Stream.close();
}

 


3.靜態代碼檢查工具

  使用Visual Studio 2015 內置檢測工具,可在微軟官方網站https://www.visualstudio.com/zh-hans/downloads/下載


 

4.掃描結果

以上問題說明代碼存在數據丟失以及內存泄漏等問題,應儘可能少使用格式自動轉換。


5.小組代碼問題說明

  • 數據結構較爲冗雜,下降了程序性能,應減小沒必要要的類的使用;
  • 異常處理不夠全面,應該覆蓋大部分的異常狀況,以便於檢查。

 

 

3、高級任務:性能測試和優化 

  設計,評審,優化

  選擇10kb,20kb,50kb大小的txt文件進行測試,程序處理時長以下:

      輸入輸出:13ms,14ms,16ms

      單詞統計:740ms,1500ms,3800ms

      詞頻排序:11ms,12ms,22ms

  單詞統計時間與文件大小呈線性相關,其餘兩個模塊佔比較小,故程序性能主要受到文件大小影響。組內共同對代碼結構和細節進行詳細審查,整理獲得優化思路以下:

    1.將統計部分中的大小寫轉換提取成單個模塊,能大幅度減小轉換函數的調用次數,隨着文件越大效果越明顯;

    2.增長單次提取字符數量,減小主框架循環次數;

    3.將字母排序單獨提取成一個模塊,即將排序算法中的比較函數替換爲純數值比較,減小內存開銷,減小排序時間,最後再遍歷數組從新調整同頻單詞順序,此方法在數組較大時可以提升程序效率。


 

  附加題

   使用MFC開發環境,設計具備圖形界面的文件選擇工具。

 


  小結

  經過基本任務、擴展任務、到高級任務的完成以及中間遇到的許多困難,體現出了軟件測試對於軟件開發的重要性。在開發過程當中,使用靜態測試工具實時地檢測本身的代碼,能夠改正本身不良的編程習慣,更能防患於未然,減小出現bug的可能;對本身的模塊進行單元測試,能夠保障本身代碼的正確性,更是對其餘開發成員和整個任務的負責,使軟件開發可以一步一個腳印地穩定開展;對性能的分析與測試,能使軟件的質量進一步提升,同事能總結開發經驗,使本身設計的模塊更加高效。

相關文章
相關標籤/搜索