【发布时间】:2014-02-27 15:26:06
【问题描述】:
今天我正在努力使我的程序更快。该程序扫描了 100,000 个虚假的社会安全号码、名字、姓氏和 gpa。我的教授已经开始谈论指针、引用和取消引用,并说使用这些可以通过传递地址来帮助加速程序。我的解释可能很糟糕,因为我在课堂上并没有真正理解这些主题,所以当你们帮助我时,我将在我的书中阅读第 9 章关于价值调用和引用调用的内容。任何帮助,将不胜感激。谢谢!!!
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<ctime>
using namespace std;
struct nameType{
string ssno;
string fName;
string lName;
double gpa;
};
int load(istream &in,nameType []);
void shellsort(nameType [],int);
void exchange(nameType &, nameType &);
void print(ostream &out,nameType [],int);
int main(void)
{
ifstream in;
ofstream out;
char infile[40],outfile[40];
nameType name[100000];
clock_t start, stop;
double secl=0;
double secs=0;
double secp=0;
double total=0;
int n;
cout << "Please enter the input data file name(NO SPACES): ";
cin >> infile;
in.open(infile);
if(in.fail()) {
cerr<<"problem input file\n"<<endl;
exit(1);
}
cout << "Please enter the output data file name(NO SPACES): ";
cin >> outfile;
out.open(outfile);
if(out.fail()) {
cerr<<"problem output file\n"<<endl;
exit(1);
}
start = clock();
n = load(in,name);
stop = clock();
secl = (double)(stop - start)/CLOCKS_PER_SEC;
cout << "Load Time: " << secl << endl;
start = clock();
shellsort(name,n);
stop = clock();
secs = (double)(stop - start)/CLOCKS_PER_SEC;
cout << "Sort Time: " << secs << endl;
start = clock();
print(out,name,n);
stop = clock();
secp = (double)(stop - start)/CLOCKS_PER_SEC;
cout << "Print Time: " << secp << endl;
total = secl + secs + secp;
cout << "Total Time: " << total << endl;
in.close();
out.close();
return 0;
}
int load(istream &in,nameType name[])
{
int n=0;
in >> name[n].ssno >> name[n].fName >> name[n].lName >> name[n].gpa;
while(!in.eof()){
n++;
in >> name[n].ssno >> name[n].fName >> name[n].lName >> name[n].gpa;
}
return n;
}
void shellsort(nameType name[],int n)
{
int gap = n/2;
bool passOk;
while(gap>0){
passOk=true;
for(int i=0; i<n-gap; i++){
if(name[i].lName>name[i+gap].lName){
exchange(name[i],name[i+gap]);
passOk=false;
}
else if(name[i].lName == name[i+gap].lName && name[i].fName > name[i+gap].fName){
exchange(name[i],name[i+gap]);
passOk=false;
}
}
if(passOk){
gap/=2;
}
}
}
void exchange(nameType &a, nameType &b)
{
nameType temp;
temp = a;
a = b;
b = temp;
}
void print(ostream &out,nameType name[],int n)
{
for(int i=0;i<n;i++){
out << name[i].ssno << " " << name[i].fName << " " << name[i].lName << " " << name[i].gpa << endl;
}
out << endl;
}
确切的分配细节---我在第 5 个项目符号上---
效率 - 时间和空间
时间和空间都是编写程序时要考虑的问题。
在此作业中,您将修改在第一个编程作业中创建的 sort_v4.cpp 程序。在该作业中,您需要处理一个整数数组。让我们用几个项目更新程序:
构建一个包含社会保险号、名字、姓氏和 GPA 的结构。 使用间隙概念的新排序技术,如类中所述,根据姓氏按升序对信息进行排序(如果姓氏相同,则需要检查名字)。排序技术称为 shell 排序。 提高效率 - 时间和空间如下所述。
每个结构元素都包含一个 ID、名字、姓氏和 gpa。假设您必须处理 100,000 名学生。该程序效率低下有两个原因
空格问题:如果社保号占12个字符,第一个和最后一个各占20个字符,gpa作为double占8个字节,那么结构元素的主数组消耗(12+20+20+8 )*100000 字节的内存。如果我们加载 100,000 个名称,这可能没问题。但是如果我们处理的平均学生数量
随着结构中成员变量数量的增加,问题变得更糟。
本次作业的重点是
将包含社会安全号码、first、last 和 gpa 的文件读入结构元素数组。处理直到 EOF。每行包含一个学生的信息。在结构内部,元素可以定义为 char [] 或字符串。如果我们使用 char [] 与字符串,你认为它会对性能产生影响吗?做一个预测。 将数组连同时间信息一起转储到文件中。 尝试新的排序技术 - 根据两个项目排序结构元素 - 名字和姓氏。 对每个功能进行计时,以查看花费最多的时间。 尝试通过使用指向结构的指针数组来改善内存的使用。 尝试通过交换指针而不是元素来加快交换速度,从而提高效率。
考虑到上述列表,作业将有三个可能的成绩。要获得 C - 14/20 分的最高成绩,您必须完成前两个项目符号。对于 B - 16/20 分的最高等级,您必须完成前 4 个项目符号。对于 A,您必须完成所有项目符号。
我建议通过实现我所说的非指针版本来开始分配。在 main 函数上方定义一个结构来保存项目。主函数应该声明结构元素的数组。调用 load、sort 和 print 函数,就像我们在第一个分配中所做的那样,进行调整以适应结构和新的排序技术,其中在交换两个元素之前需要考虑两个项目。注意:这次我想看看交换功能。这将为您提供总共 4 个功能。确保遵循第一个编程作业中所述的准则。
对于所有尝试 A 程序的人,请确保在继续之前完成并测试了 B 的基本程序。制作该程序的副本并按如下方式修改程序:
通过在定义中放置 * 将结构元素数组更改为指向结构元素的指针数组。 使用 new(或 malloc),在读取结构成员的值之前为一个结构元素动态创建空间。 当你交换两个元素时,交换两个指向结构元素的指针,而不是结构元素本身。 看看你的非指针版本和指针版本的时间。有显着区别吗?
以下是有关计时一项功能的信息。
#include<ctime>
//Create a couple variables of clock_t type.
clock_t start, stop;
start = clock();
load(x, n); //call a function to perform a task
stop = clock();
cout << "load time: " << (double)(stop - start)/CLOCKS_PER_SEC << endl;
函数clock()返回程序启动后发生的cpu时钟周期数。理想情况下,上述代码中的 start 应该是 0。为了能够了解一个函数需要多少时间,您必须将经过的时间转换为秒。这是通过获取开始和停止之间的差异、类型转换,然后除以系统定义的 CLOCKS_PER_SEC 来实现的。在 linus public(或实验室中的外星机器)上是 1,000,000。另请参阅有关该主题的课堂笔记。以下是排序数据末尾应显示的示例。
加载时间:0.05 排序时间:2.36 打印时间:0.01 总运行时间:2.42
错过最后期限的罚款,每天 1 分,最多 7 天。截止日期后 7 天不接受课程。
【问题讨论】:
-
没有人会挥动魔杖让你的程序更快。根据输入文件的结构,shellsort 可能不是最佳的。使用分析器查看每行代码的执行时间。
标签: c++ performance