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] = '';
                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

原文地址:https://www.cnblogs.com/KamiForever/p/9756000.html