利用vs2012对统计词频进行性能分析

    计算机软件使用已经渗透到我们生活的方方面面,而软件工程的方法指导软件开发,可以少走弯路,更易开发出高质量的软件。

    软件工程是一个复杂的系统工程,它融合计算机科学、统计学、管理学、心理学等多门学科。通过学习这门课程我们将了解软件项目是否成功,不仅取决于是否具有专业技能,还取决于能否发挥人的作用,组织好项目的过程,贯彻软件开发的最佳工程实践。

作为一名计算机专业的学生,编写实现功能的代码只是最基本的,而一位优秀的程序员更应该关心自己写的代码的性能。毕竟写代码是一步步优化的过程,通过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分析的功能,为以后的代码优化提供了良好的基础。如有错误,望大家指教。


 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值