哪位大哥帮我看看这个程序该如何优化运行速度?
貌似中间字节高低位排序并写入文件的操作执行起来效率级低啊,一秒钟才处理几十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字节是致命问题,把对于硬盘的频繁读取变成对内存读取,修改后的程序确实快多了。