读书人

哪位大哥帮小弟我看看这个程序该怎么优

发布时间: 2012-08-08 14:32:45 作者: rapoo

哪位大哥帮我看看这个程序该如何优化运行速度?
貌似中间字节高低位排序并写入文件的操作执行起来效率级低啊,一秒钟才处理几十K,为什么这么慢啊?

C/C++ code
// strip.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <fstream>#include <string>#include <cstdlib>inline void exch(char ex[],long size){    char c;    switch (size)    {    case 4:        {            c=ex[0];ex[0]=ex[3];ex[3]=c;            c=ex[1];ex[1]=ex[2];ex[2]=c;            break;        }    case 3:        {            ex[0]=ex[3];            c=ex[1];ex[1]=ex[2];ex[2]=c;            break;        }    case 2:        {            ex[0]=ex[3];            ex[1]=ex[2];            break;        }    case 1:        {            ex[0]=ex[3];            break;        }    }}int _tmain(int argc, _TCHAR* argv[]){    using namespace std;    ifstream fin;    fstream fout;    ofstream fout2;    fin.open("test.dat", ios_base::in |ios_base::binary);//打开数据文件    fout2.open("testout.dat",ios_base::out|ios_base::binary);    if (fin.is_open())    {        long m;//EB905717末(第m字节)        long n;//数据长度        long p;//读指针位置        long end;//一帧的压缩数据末(第end字节)        long size;//重新排序时的数组长度        char ex[4];        char head[4]={'\xEB','\x90','\x57','\x17'};                while (1) {            for (fin.read(ex,4);memcmp(ex,head,4);)            {                fin.seekg(-3,ios::cur);                fin.read(ex,4);                if(fin.eof())break;//读指针到达文件尾时跳出                            }//读取4个字节到ex[4],如果ex[4]不为0xEB905717,则读指针位置倒退3个字节            if(fin.eof())break;            m=fin.tellg();//EB905717末(第m字节)            fin.seekg(8,ios::cur);            p=fin.tellg();            fin.read(ex,4);//把压缩数据长度写入ex            p=fin.tellg();            exch (ex,4);            n=*((long *)ex);//数据长度转为long型            end=m+12+n;            p=fin.tellg();            while((end-p)>=4){//读指针(p=tellg)距离数据尾(m+13+n)大于等于4字节,size=4,向后读取size(4)个字节,进行数组长度为size(4)的字节顺序排列,并在fileout写入size(4)个字节                size=4;                fin.read(ex,4);                if(fin.eof())break;                p=fin.tellg();                exch (ex,4);                fout2.write(ex,4);            }            if( ((end-p)<4) & ((end-p)>0) ){//读指针(p=tellg)距离数据尾(m+13+n)少于4字节,size=n%4,向后读取4个字节,进行数组长度为size的字节顺序排列,并在fileout写入size个字节                size=n%4;                fin.read(ex,4);                if(fin.eof())break;                p=fin.tellg();                exch (ex,size);                fout2.write(ex,size);            }        }    }    fin.close();    fout2.close();    return 0;}


[解决办法]
如果你扔掉fstream,用Windows API的,标准C的IO、C#的IO、JAVA的IO,反正时除了C++以外的任何一种IO,直接能快很多

然后说说代码中的问题,一次读4字节太少,多读一些,你可以在内存里分块处理,这样即便不改C++的IO也能快一些,C++ IO的默认缓冲区通常也不是最合理的,调整下缓冲区也可能缓解性能问题
[解决办法]
推荐用 intel VTune , 来分析性能。
用 intel parallel studio 的 inspector 来 诊断 内存/线程/句柄等资源的竞争和泄露以及....
[解决办法]
楼主何不一次将文件都读入内存,这样就快很多了。当然,文件过大就另说了
[解决办法]
最后一个fin.read(ex,4);
应该是fin.read(ex,size);

几乎所有的f.tellg都不需要,直接自行计算

求长度不用exch,直接ch[0]<<24+ch[1]<<16+ch[2]<<8+ch[3]

exch可以重写,效率比较低

求出长度后,一次读出->内存中颠倒->最后一次写入,减少文件操作

寻找同步头时,先读出1K字节,然后在这1K里搜索同步头,完全不需要seekg操作
[解决办法]
一次读取512个字节或者其他什么系统方面规定的block块的数据,这样系统有优化。
从结构上,尽量使用系统提供的异步IO接口,同步IO接口是效率杀手。
想从io上提升效率,就要抛开一切标准的io接口,而尽可能贴近系统,贴近底层,多用异步。
------解决方案--------------------


一次只读4字节是致命问题,把对于硬盘的频繁读取变成对内存读取,修改后的程序确实快多了。

探讨
C/C++ code

// strip.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <cstdlib>
#include <memory.h>
#include <iostream>

//#include "CodeBlockType……

读书人网 >C++

热点推荐