读书人

请STL高手帮忙:如何加速fstream(ofst

发布时间: 2012-02-20 21:18:23 作者: rapoo

请STL高手帮忙:怎么加速fstream(ofstream, ifstream)的操作
首先说明,输入输出都是二进制的方式,也就是用ofstream的write输出,用ifstream的read读入。

现在有一个测试用的结构
struct Test {
int v1;
int v2;
int v3;
int v4;
int v5;
int v6;
}

产生1000000个对象用于输出测试(保存在一个std::vector中)。

for (int i = 0; i < 1000000; i++) {
Test& t = v[i];
out.write((const char*) &v1, sizeof(int));
out.write((const char*) &v2, sizeof(int));
out.write((const char*) &v3, sizeof(int));
out.write((const char*) &v4, sizeof(int));
out.write((const char*) &v5, sizeof(int));
out.write((const char*) &v6, sizeof(int));
}

这样写1000000条数据的时间是26秒左右。

如果我自己定义一个缓冲类来写,时间会在7秒左右。自定义的缓冲类如下:

class MyOStream : public ofstream
{
public:
static const BUF_SIZE = 10240;

MyOStream(const char* filename, ios_base::openmode _Mode = ios_base::out)
: ofstream(filename, _Mode), current(0) {}

void write(const char* buffer, unsigned int size)
{
if (current + size > BUF_SIZE) {
this-> flush();
}
memcpy(this-> buffer, buffer, size);
current += size;
}

void flush()
{
ofstream::write(this-> buffer, current);
current = 0;
}

private:
char buffer[BUF_SIZE];
int current;
};

_____________________________________________________
现在问题是——用什么办法,不使用自定义的输出流,只使用std的缓冲机制,把速度提升起来!!

我试过out.rdbuf()-> setbuf(....),设置了一个100K的缓冲区,输出操作同样消耗26秒左右的时间,似乎缓冲区没起到作用,不知为何?

注,所有时间以自己机器上为准,机器不同时间肯定是不同的。

[解决办法]
用fwrite会快一点。
[解决办法]
你这样循环花在函数调用上的时间就不少了, vector 保证了内存布局的,这样就快了:
out.write((char*)&v[0], v.size() * sizeof(Test));
[解决办法]
说说原始的需求
------解决方案--------------------


你要提高多少倍?
[解决办法]
你都自己写了一个缓冲类,就用它好了,岂不省事。
[解决办法]
优化的余地不大
[解决办法]
写个成程序,发现它的那个缓冲设了好像没什么影响...


#include "stdio.h "
#include "stdlib.h "
#include "iostream "
#include "string "
#include "fstream "
#include "windows.h "

using namespace std;

struct Test {
int v1;
int v2;
int v3;
int v4;
int v5;
int v6;
};

int _tmain(int argc, _TCHAR* argv[])
{
ofstream out( "text.txt ", ios_base::binary);

char buf[10240];

basic_filebuf <char,char_traits <char> > * strbuf = out.rdbuf();

strbuf-> pubsetbuf(buf, 10240);

Test* v = new Test[1000000];

DWORD s = GetTickCount();

for (int i = 0; i < 1000000; i++) {
Test& t = v[i];
out.write((const char*) &t.v1, sizeof(int));
out.write((const char*) &t.v2, sizeof(int));
out.write((const char*) &t.v3, sizeof(int));
out.write((const char*) &t.v4, sizeof(int));
out.write((const char*) &t.v5, sizeof(int));
out.write((const char*) &t.v6, sizeof(int));
}
out.flush();

DWORD d = GetTickCount();

cout < <(d - s) / 1000.f < <endl;

return 0;
}


[解决办法]
我也感兴趣看看,还在试试中

是了

你可以直接这样

out.rdbuf()-> setbuf(

setbuf好像是私有成员
[解决办法]
搂主,你试试这

for (int i = 0; i < 1000000; i++) {
Test& t = v[i];

out.rdbuf()-> sputn((const char*) &t.v1, sizeof(int));
out.rdbuf()-> sputn((const char*) &t.v2, sizeof(int));
out.rdbuf()-> sputn((const char*) &t.v3, sizeof(int));
out.rdbuf()-> sputn((const char*) &t.v4, sizeof(int));
out.rdbuf()-> sputn((const char*) &t.v5, sizeof(int));
out.rdbuf()-> sputn((const char*) &t.v6, sizeof(int));
}
out.flush();
[解决办法]
为什么要把变量定义放在循环内??好像编译器也不一定会优化吧??说错了请不吝扔砖....
[解决办法]
不知lz的编译和运行环境如何?
我用vs2005、stlport 5.1.2、release版的情况下,直接使用ofstream输出,平均耗时也是2秒左右;最大耗时也是3秒多。代码如下:
#include "stdafx.h "
#include <fstream>
#include <iostream>
#include <Windows.h>

using namespace std;

struct Test {
int v1;
int v2;
int v3;
int v4;
int v5;
int v6;
};

int _tmain(int argc, _TCHAR* argv[])
{
ofstream out( "text.txt ", ios_base::binary);

Test* v = new Test[1000000];

DWORD s = GetTickCount();

for (int i = 0; i < 1000000; i++) {
Test& t = v[i];
out.write((const char*) &t.v1, sizeof(int));
out.write((const char*) &t.v2, sizeof(int));
out.write((const char*) &t.v3, sizeof(int));
out.write((const char*) &t.v4, sizeof(int));
out.write((const char*) &t.v5, sizeof(int));


out.write((const char*) &t.v6, sizeof(int));
}
out.flush();

DWORD d = GetTickCount();

cout < <(d - s) / 1000.f < <endl;

return 0;
}

读书人网 >C++

热点推荐