20180925-3 效能分析
作业要求参见[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2145]
git地址:https://git.coding.net/KamiForever/newwf.git
一、得出程序运行时间
运行截图如下:
第一次运行时间为 0.564 s
第二次运行时间为 0.402 s
第三次运行时间为 0.406 s
平均运行时间为:0.457 s
CPU参数:Intel(R) Core(TM) i7-8750M CPU @ 2.20GHz 2.20GHz
二、猜测程序瓶颈
猜测一:在进行字符输入的时候会用很多时间
while((c = getchar()) != EOF) { if((c >= 65 && c <= 90) || (c >= 97 && c <= 122)) { if(c >= 65 && c <= 90) c += 32; word[i++] = c; before = 1; } else { if(before) { word[i] = '\0'; Hash(word); i = 0; before = 0; } } }
猜测二:在运用hash去插入不相同字符串的时候会用很多时间。
while(1) { if(words[t].cnt == 0) { words[t].cnt = 1; strcpy(words[t].content, word); wordtotal += 1; wordcnt += 1;; return; } else { if(strcmp(words[t].content, word) == 0) { words[t].cnt += 1; wordtotal += 1; return; } else { if(t == Maxn - 1) t = 0; else t += 1; } } }
在输入中每一次字符都需要一个o(1)的时间,代码中主要设计的问题就是再把整个文章都输入进来,在输入部分应该会占用很多时间。hash处理上,hash中字符串hash值相同的时候进行字符串比较会比较占用时间,如果对比次数过多也会是一个比较花时间的点。
三、利用profile找出瓶颈
CPU使用率截图:
函数调用次数:
函数详细信息:
如图所示可以发现比较花时间的两个地方一个是在输入字符fgetc()上,另一个实在Hash插入中。
注:vs进行分析,得到了报错,不支持IO重定向测试,于是我把代码先改成用文件输入而不是重定向输入,这样应该返回而更加费时间。
四、优化程序
关于输入方式地方我实在是没有更好的优化方式,在hash的地方尝试更改hash时hash的方式,让能够进行判定的位数增大,把匹配的地方进行了改写。
void Hash(char word[]) { int len = strlen(word); if(len >= 6) len = 6; int t = 0; for(int i = 0; i < len; i++) { t = t * 10; t += (word[i] - 97); } t = t % Maxn; for(int i = t; i < Maxn; i++) { if(words[i].cnt == 0) { words[i].cnt = 1; strcpy(words[i].content, word); wordtotal += 1; wordcnt += 1;; return; } else { if(strcmp(words[i].content, word) == 0) { words[t].cnt += 1; wordtotal += 1; return; } if(i == Maxn - 1) i = -1; } } }
五.对改进程序进行profile测试
效能分析中,输入getword函数中输入部分占比例增大,hash函数占比例减小,可见对hash方式的改变使速度有所加快。
第一次运行时间为 0.522 s
第二次运行时间为 0.350 s
第三次运行时间为 0.348 s
平均运行时间为0.407 s
比修改前快了0.050 s