首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

请STL高手帮忙:如何加速fstream(ofstream, ifstream)的操作

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

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

热点排行