在我的程序中,我读了一个文件(这里只有一个大约200k数据点的测试文件,之后会有数百万。)现在我做的是:
for (int i=0;i<n;i++) {
fid.seekg(4,ios_base::cur);
fid.read((char*) &x[i],8);
fid.seekg(8,ios_base::cur);
fid.read((char*) &y[i],8);
fid.seekg(8,ios_base::cur);
fid.read((char*) &z[i],8);
fid.read((char*) &d[i],8);
d[i] = (d[i] - p)/p;
z[i] *= cc;
}
因此n表示要读入的点数。
然后我再次用
写下它们for(int i=0;i<n;i++){
fid.write((char*) &d[i],8);
fid.write((char*) &z[i],8);
temp = (d[i] + 1) * p;
fid.write((char*) &temp,8);
}
因此写作速度比读数快(用clock_t测量的时间)
我的问题现在。我是否在阅读中做了一些相当愚蠢的错误,或者可以预期这种行为?
我正在使用带磁盘的Win XP。
你的magu _
答案 0 :(得分:13)
您经常使用seekg
。我看到你用它来跳过字节,但你也可以读完整个缓冲区,然后跳过缓冲区中的字节:
char buffer[52];
for (int i=0;i<n;i++) {
fid.read(buffer, sizeof(buffer));
memcpy(&x[i], &buffer[4], sizeof(x[i]));
memcpy(&y[i], &buffer[20], sizeof(y[i]));
// etc
}
但是,您可以定义一个表示文件中数据的结构:
#pragma pack(push, 1)
struct Item
{
char dummy1[4]; // skip 4 bytes
__int64 x;
char dummy2[8]; // skip 8 bytes
__int64 y;
char dummy3[8]; // skip 8 bytes
__int64 z;
__int64 d;
};
#pragma pack(pop)
然后声明这些结构的数组并一次读取所有数据:
Item* items = new Item[n];
fid.read(items, n * sizeof(Item)); // read all data at once will be amazing fast
(评论:我不知道x
,y
,z
和d
的类型,所以我假设__int64
在这里)
答案 1 :(得分:4)
我个人(至少)会这样做:
for (int i=0;i<n;i++) {
char dummy[8];
fid.read(dummy,4);
fid.read((char*) &x[i],8);
fid.read(dummy,8);
fid.read((char*) &y[i],8);
fid.read(dummy,8);
fid.read((char*) &z[i],8);
fid.read((char*) &d[i],8);
d[i] = (d[i] - p)/p;
z[i] *= cc;
}
做一个结构,或一次性读取大量数据(比如添加第二层,一次读取4KB,然后使用一对“跳过”和“获取”不同的函数字段会有点多工作,但可能要快得多)。
另一种选择是在Linux中使用mmap
或在Windows中使用MapViewOfFile
。此方法减少了一小部分读取文件的开销,因为将数据传输到应用程序所需的副本少一个。
编辑:我应该添加“确保进行比较测量”,如果您的应用程序要在多台计算机上运行,请确保在多种类型的计算机上进行测量,使用不同的磁盘驱动器替代方案,处理器和记忆。你真的不想调整代码,以便它在你的机器上运行速度提高50%,但在另一台机器上运行速度提高25%。
答案 2 :(得分:1)
assert()语句是此代码中最重要的部分,因此如果您的平台发生更改并且本机类型的宽度发生更改,则断言将失败。而不是寻求,我会读到虚拟区域。 p *变量使代码更容易阅读,IMO。
assert(sizeof x[0] == 8);
assert(sizeof y[0] == 8);
assert(sizeof z[0] == 8);
assert(sizeof d[0] == 8);
for (int i=0;i<n;i++) {
char unused[8];
char * px = (char *) &x[i];
char * py = (char *) &y[i];
char * pz = (char *) &z[i];
char * pd = (char *) &d[i];
fid.read(unused, 4);
fid.read(px, 8);
fid.read(unused, 8);
fid.read(py, 8);
fid.read(unused, 8);
fid.read(pz, 8);
fid.read(pd, 8);
d[i] = (d[i] - p)/p;
z[i] *= cc;
}