今天我正在努力让我的程序更快。该程序扫描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排序。 提高效率 - 时间和空间如下所述。
每个struct元素都包含ID,名字,姓氏和gpa。假设您必须处理100,000名学生。由于两个原因,该计划效率低下
空间问题:如果社会安全号码占用12个字符,则第一个和最后一个占用20个字符,并且作为双倍的gpa占用8个字节,然后结构元素的主要数组消耗(12 + 20 + 20 + 8) )* 100000字节的内存。如果我们加载100,000个名字,这可能没问题。但是,如果我们处理的学生平均数量<50,000,那么就会浪费大量的内存。 时间问题:当你交换两个乱序的元素时,60个字节大约移动3次。在内存中移动总共180个字节。再次,效率低下。
随着结构中成员变量的数量增加,问题变得更糟。
这项任务的重点是
将包含社会安全号码,first,last和gpa的文件读入结构元素数组。处理直到EOF。每行包含有关一名学生的信息。在结构内部,元素可以定义为char []或字符串。如果我们使用char [] vs字符串,你认为它会对性能产生影响吗?做一个预测。 将数组与定时信息一起转储到文件中。 尝试新的排序技术 - 根据两个项目排序结构元素 - 名字和姓氏。 计算每个功能的时间,以查看花费最多时间的位置。 尝试使用指向结构的指针数组来改进内存的使用。 尝试通过交换指针而不是元素来加快交换速度,从而提高效率。
考虑到上面的列表,分配将有三种可能的等级。对于C - 14/20点的最高等级,您必须完成前两个子弹。对于B - 16/20点的最高等级,您必须完成前4个子弹。对于A,您必须完成所有子弹。
我建议通过实现我称之为非指针版本来开始赋值。在main函数上面定义一个结构来保存项目。 main函数应声明struct元素数组。调用加载,排序和打印函数,就像我们在第一个赋值中进行调整一样,以适应结构和新的排序技术,在交换两个元素之前需要考虑两个项目。注意:这次我想查看交换功能。这将为您提供总共4个功能。确保遵循第一个编程任务中规定的指导原则。
对于所有正在尝试A程序的人,请确保在继续之前已经完成并测试了B的基本程序。制作该程序的副本并按如下方式修改程序:
通过在定义中放置*,将struct元素数组更改为指向struct元素的指针数组。 使用new(或malloc),在读入结构成员的值之前,为一个结构元素动态创建空间。 当你交换两个元素时,交换两个指向struct元素的指针而不是struct元素本身。 看一下非指针版本和指针版本的时间。有显着差异吗?
以下是关于计时一个功能的信息。
#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时钟周期数。理想情况下,从上面的代码开始应为0.为了能够了解函数花费多少时间,您必须将经过的时间转换为秒。这是通过获取开始和停止之间的差异,类型转换,然后除以系统定义的CLOCKS_PER_SEC来实现的。在linus公共(或实验室中的外来物品机器)是1,000,000。另请参阅有关该主题的课堂笔记。以下是应该出现在排序数据末尾的示例。
加载时间:0.05 排序时间:2.36 打印时间:0.01 总运行时间:2.42
错失最后期限的罚款,每天1点,最多7天。课程截止日期后7天不接受。
答案 0 :(得分:0)
如果你看这里:How are arrays passed?
数组已经作为指针传递,你的std :: swap(你称之为“exchange”)的实现已经通过引用传递了。所以这不是你的问题。你的教授有没有抱怨你的程序执行速度?
答案 1 :(得分:0)
在程序中占用大量执行时间的地方称为瓶颈。
常见的瓶颈是文件输入和输出。您可以通过减少或优化瓶颈来加快程序运行速度。
从文件中读取许多小块数据比读取一大块数据需要更多时间。例如,使用一个请求读取10行数据比读取一行数据的10个请求更有效。
访问内存比从文件读取更快,更快。
一般模式是:
1.将大量数据读入内存
2.处理数据
3.根据需要重复1。
因此,您可以将“block”读取命令istream::read
用于字节数组中。使用字节数组中的一行数据加载一个字符串并处理该行。从数组重复加载,直到用完为止,然后从文件重新加载。