1. 程式人生 > >軟件工程第三次作業 - 效能分析

軟件工程第三次作業 - 效能分析

字符 耗時 rds words 是否 有變 行存儲 導致 分隔

要求0:以 戰爭與和平 作為輸入文件,重讀向由文件系統讀入。連續三次運行,給出每次消耗時間、CPU參數。

第一次運行結果:

技術分享

技術分享

技術分享

本次程序運行所消耗的時間為1.2秒。

第二次運行結果:

技術分享

技術分享

技術分享

本次程序運行所消耗的時間為936毫秒。

第三次運行結果:

技術分享

技術分享

技術分享

本次程序運行所消耗的時間為975毫秒。

要求1:給出你猜測程序的瓶頸。你認為優化會有最佳效果,或者在上周在此處做過優化 (或考慮到優化,因此更差的代碼沒有寫出) 。

上周的代碼我使用的是結構體數組來對分割好的單詞進行存儲並采用冒泡排序,效果非常不理想,統計完war_and_peace.txt這個文件需要7秒左右。

struct words
{
	int num;
	char word[20];
};
while (feof(fp) == 0)
{
	fscanf(fp, "%s", temp); //輸入文件名
	//字符串過濾
	dispose(temp);
	if (temp != NULL)
	{
		int i = 0;  //標記返回值
					//判斷是否有重復
		if ((i = issame(str, temp, n)) != 0)
		{
			//有重復
			str[i].num += 1;
		}
		else
		{
			//沒有重復
			sprintf(str[n].word, temp);
			str[n].num += 1;
			n++;
		}
	}
}

這周代碼存儲單詞采用了哈希表存儲並采用快速排序,效果有了顯著的提升,統計war_and_peace.txt這個文件僅需要900毫秒左右。

Hashtable strTab = new Hashtable();
for (int i = 0; i < strArr.Length; i++)
{
    if (strArr[i] != "")
    {
        if (strTab.Contains(strArr[i]))
        {
            //已有
            strTab[strArr[i]] = (int)strTab[strArr[i]] + 1;
        }
        else
        {
            //沒有
            strTab.Add(strArr[i], 1);
        }
    }
}

因為哈希表有查找效率高的優點,所以改用了哈希表之後運行速度有了明顯的提升。

要求2:通過 profile 找出程序的瓶頸。給出程序運行中最花費時間的3個函數(或代碼片斷)。要求包括截圖。

技術分享

本程序中,以上三個函數最花費時間。

上面三個函數中最花費時間的是Statistics函數,因為函數中有對字符串進行分割的操作:

string[] strArr = str.Split(ch);

上面代碼通過Split()函數對字符串進行分割,導致花費的時間非常多。

要求3:根據瓶頸,"盡力而為"地優化程序性能。

本人嘗試過一個字符一個字符的讀取,然後當讀取到自定義的分隔符後,將讀取出來的字符串存入到哈希表中,但是這個方法更慢,所以目前最優的方案是就是用Split()函數來對字符串進行分割。

要求4:再次 profile,給出在 要求1 中的最花費時間的3個函數此時的花費。要求包括截圖。

由於本人無力對程序進行優化,所以此時最花費時間的三個函數沒有變。

技術分享

軟件工程第三次作業 - 效能分析