作业要求参见[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] = ' ';
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