zoukankan      html  css  js  c++  java
  • 软件工程第2次作业—效能分析

    作业要求的博客链接:https://edu.cnblogs.com/campus/nenu/2016CS/homework/2139

    git仓库地址:https://git.coding.net/isak_even/wfAnalysis.git

    第一次作业—词频统计v1.0:https://www.cnblogs.com/kongwy/p/9662364.html

    一、项目概要:

      本次项目实现的是词频统计的效能优化,v1.1主要改进功能三,目前测试《战争与和平》结果的最优时间为0.385。

    二、效能分析

    1.以war_and_peace.txt作为测试文件,连续三次运行,给出每次消耗时间。

    原始代码没有使用命令行参数,经过改进后测试截图如下:

    2.猜测瓶颈

     (1)第一个瓶颈应该就是读文件,将文本处理成字符串。这次处理的是3.14MB的文本文件,读文件一定是耗时最长的单元,这个地方应该优化一下。估计优化后时间会缩短一半。

    /* ----实现读取指定文件的功能-----*/
    void readtxt(string filename)
    {
        ifstream file;
        file.open(filename.c_str());//注意一定要转化为 char *
        string s;        //每次读取一行txt文件返回的字符串
        while(getline(file, s))//按行读取
        {
            str=s+' '+str;//加空格确保分割开行尾和行首的两个单词
        }
        transform(str.begin(), str.end(), str.begin(), ::tolower);//将大写转化为小写
        file.close();    //关闭文件
    }

     (2)第二个是分割字符串,并且统计合法单词的词频。理由同上,测试数据过大所以耗时长,优化后时间会缩短。

    for (long i=0;i<str.length();i++)
        {
            while(str[i]>='0'&&str[i]<='9'||str[i]>='a'&&str[i]<='z')
            {
                temp=true;
                b+=str[i];
                i++;
            }
            if(temp)
            {
                word=b;
                if(word[0]>'9'||word[0]<'0') //判断第一个字符是不是数字
                {
                    ++word_count[word];
                    vec.push_back(word);
                }
    
                b="";
                word="";
                temp=false;
            }
        }

    3.利用profile找出瓶颈并优化

     第一次profile的截图如下:

     (1)可以看出getline(file,s)和字符串的合并是耗时最长的。分析后决定把读文件和分割出合法字符串合在一起,读完一行就进行处理,就可以省略str = s+' '+str。

     (2)调试后发现transform函数也比较耗时,便将处理大小写转变为判断字符,确定是大写字母再转化为小写字母。

     (3) 将for (long i = 0; i<str.length(); i++) 转变为 long a = str.length();  for (long i = 0; i<a; i++),这样不需要每次循环都调用length()函数。

    优化后第二次profile截图如下

     (1)再次测试后此时耗时最长的是b=b+str[i]。参考博客:http://www.cnblogs.com/chuncn/archive/2009/02/13/1390176.html 我改为:b.append(1,str[i]);

     (2)++word_count[word]耗时也长。map函数是自动排序的,这样效率会低一点,所以我换成unordered_map<string, long> word_count;

    参考博客:http://www.cnblogs.com/me115/archive/2013/06/05/3117967.html

    (3)最后将功能一和二共同改进一下。

    4.优化后的profile截图

    5.优化后时间

    三、自我评估

    个人基本情况见第零次作业 博客地址:https://www.cnblogs.com/kongwy/p/9611339.html

    这次作业主要是优化代码,提高效率,也是解决自己上次遗留的问题。

    (1)在初步测试的时候其实不太好用,通过参考其他人的博客,发现没有使用命令行参数,就是int main(int argc, char* argv[]),更改之后代码也简单了不少。

    (2)用ptime测试时发现电脑配置对代码的运行效率影响较大,所以在室友的笔记本和学院的机房都进行了多次测试。

    (3)安装VS,并且启用性能分析,通过阅读《构建之法》第二章基本了解到抽样和代码注入的区别。这次采用的主要还是抽样。

    (4)发现VS要求比较严格,代码不能用头文件#include<bits/stdc++.h>以及需要将 sscanf改为sscanf_s。

    (5)优化代码之后大概减少了四十行,速度提高了十倍左右。

  • 相关阅读:
    利用kettle中的JS来完成ETL数据校验
    spring cloud学习地址
    centos7 卸载 gitlab
    为什么WEB-INF外的jsp无法根据cookie享受国际化
    改变maven父子项目视图为树状
    maven profiles、filters、resources学习笔记 及 常用 plugin demo
    Tomcat 签名认证配置简例
    CentOS 开机启动
    Tomcat 关闭时报错
    比较全的log4j示例
  • 原文地址:https://www.cnblogs.com/kongwy/p/9721197.html
Copyright © 2011-2022 走看看