请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;
}