计算机软件使用已经渗透到我们生活的方方面面,而软件工程的方法指导软件开发,可以少走弯路,更易开发出高质量的软件。
作为一名计算机专业的学生,编写实现功能的代码只是最基本的,而一位优秀的程序员更应该关心自己写的代码的性能。毕竟写代码是一步步优化的过程,通过VS2012的分析,可以直接清晰的看到自己写的代码哪些部分是比较耗时,比较占用CPU,然后知道自己的代码需要改进哪些地方。
少废话,下面就简单说一下这次的实验。
一、程序说明及结果
首先,老师这次给的作业是写一个程序,分析一个文本文档中各个词出现的频率,并且把频率最高的
10个词打印出来,我的文本文件大约是247KB。我想了两种数据结构:一种是数组,另一种是双向链表,并分别实现。二者的实验结果显然是一样的,如下图所示:
二、二者的性能分析与比较
1、数组数据结构:
(1)从上图可以看出整个过程运行完大概需要10秒钟左右的时间,在第8-9秒之间CPU使用百分比是最高的,大概是18%左右。
(2)从下图知,fenxi()函数消耗资源最多,大约占了60%左右,所以要想提高效率,就必须优化该函数!
(3)点击该函数进行定位,就可以找到原因:每次循环都要调用strcmp()函数比较!这就是效率不高的地方!!!
2、双向链表实现
(1)从上图可以看出整个过程运行完大概需要3.5秒钟左右的时间,在第1-3秒之间CPU使用百分比是最高的。
(2)从下图知,也可以很清晰的看出哪个函数消耗资源最多。
3、简要看一下我们编写的readfile()函数,虽然占用很高的cpu,大约85.3%,但是由上图知,该样本只占用2.07%的比例,所以说,已经大大提高了程序的效率!
三、核心代码
#include "head.h"
Wordcount::Wordcount(){
ptr = NULL;
}
void Wordcount::readFile(){
ifstream in;
in.open("data.txt", ios::in);
if(!in)
return;
string str = "";
Word * p, *pre;
char ch;
while(!in.eof()){
in.get(ch);
if(ch == ' ' || ch == 10)
continue;
if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'))
{
while(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')){
if('A' <= ch && ch <= 'Z')
ch += 32;
str += ch;
if(!in.eof())
in.get(ch);
else
return;
}
///
//一个单词结束
Word * wtemp = new Word;;
wtemp->count = 1;
wtemp->w = str;
wtemp->next = NULL;
wtemp->par = NULL;
str = "";
//若为第一个单词
if(ptr == NULL){
ptr = wtemp;
}
else{
//与前面的单词比较
p = pre = ptr;
while(p){
pre = p;
if(p->w == wtemp->w){
p->count++;
//更新链表
update(p);
break;
}
else
p = p->next;
}
//当前单词不存在时
if(!p){
pre->next = wtemp;
wtemp->par = pre;
}
}
}
}
in.close();
}
//更新链表的排序
void Wordcount::update(Word * pn){
Word * p = NULL;
Word * q = NULL;
if(pn != ptr)
while((pn->par != NULL) && (pn->count > pn->par->count)){
//如果与头结点交换,需更新ptr指针,即头指针
if(pn->par == ptr)
ptr = pn;
p = pn->next;
q = pn->par;
///注意双链表共有6个节点需要更新
//更新当前节点的下一节点的par指针,注意判断其是否为空
if(pn->next)
pn->next->par = pn->par;
pn->next = pn->par;
pn->par = pn->par->par;
if(q->par)
q->par->next = pn;
q->par = pn;///
q->next = p;
}
}
void Wordcount::reaultOut(){
int i;
Word * p = ptr;
if(p != NULL){
for(i = 0; i < 10 && p; i++){
cout << p->w << " " << p->count << endl;
p = p->next;
}
}
}
四、小结
我们通过实验,找到了代码效率不高的地方,并成功运用双向链表使其改进,并且通过本次实验,学习使用了vs2012分析的功能,为以后的代码优化提供了良好的基础。如有错误,望大家指教。