代码主旨是将分析obReadBuf缓冲区里面的数据,pbReadBuf是UINT型,总共有nSampleSize==11000000个,下面是我编的处理pbReadBuf里面的数据
char strVar;
for(i=0; i<nSampleSize;i++)
{
    if(pbReadBuf[i]^bPre!=0)
      bPre=pbReadBuf[i];
    else
      itoa((int)(bPre[j]), strVar, 2);
}
这个循环太久了,要2个小时左右,哪位高手能帮忙优化一下,用内存操作可以么?

解决方案 »

  1.   

    我晕,11000000次循环,做一些简单的判断也用不着2个小时吧,你的是什么系统啊if(pbReadBuf[i]^bPre!=0)这句改成if(pbReadBuf[i] != bPre )速度也能快一些
      

  2.   

    itoa((int)(bPre[j]), strVar, 2);
    我对这句很不理解请参照:
    if(pbReadBuf[i]^bPre!=0)bPre=pbReadBuf[i];
    还有:
    char strVar;
      

  3.   

    这是一段分析采样数据的代码,共11000000采样点,每个采样点是UINT型,即32位,我的电脑是酷睿双核2.8G,外加DDRII 2G内存,我测试过,即使for循环里只有一个printf语句,循环也要2个多小时,而且从打印的信息来看,没有死循环,所以我想降低循环次数是解决问题的关键,我在想,像WinRAR这种软件也是分析数据进行压缩,它怎么可以做的这么快,应该是有解决之道的,就渴望各位高手赐教了,谢谢了!!!
      

  4.   

    char strVar;
    for(i=0; i<nSampleSize;i++)
    {
      if(pbReadBuf[i]^bPre!=0)
      bPre=pbReadBuf[i];
      else
      itoa((int)(bPre[j]), strVar, 2);
    }
    优化如下:
    char strVar;
    for(i=nSampleSize; i>0; i--)
    {
      if(pbReadBuf[i]!=bPre)
      bPre=pbReadBuf[i];
      else
      itoa((int)(bPre[j]), strVar, 2);
    }
    优化原理:其实就是for中的判断,优化之后是直接判断大于等于0的后缀,而你的判断过程是要先sub 然后判断jl  多了一个指令时间。
    还有pbReadBuf[i]^bPre!=0 这句是要判断他俩不相等,你就直接判断,绕个弯干嘛。本来是一个过程,你这样多加了一个指令时间。
    同过这个小循环来看,最后的itoa很可能是执行不到的,当然,程序不全,我也没办法真正弄明白你的意图。
      

  5.   

    国内的"好压",是开源的,算法应该不差于winrar
      

  6.   

    printf是IO输出,当然很慢了。
    我试了,11000000个采样点,赋值再加上做一遍itoa转换,
    几秒钟就完成了,debug版本。
      

  7.   

    itoa((int)(bPre[j]), strVar, 2);
    应该是这句耗时比较多
    你将这句注释掉看看效果
    如果是的话考虑一下有没有什么替换的方法
      

  8.   

    不是循环的问题!printf当然慢了
    你应该找找其他的原因
      

  9.   

    整个程序是要将采样缓冲区里的数据转换成文本格式的VCD(Value Change Dump File)文件,VCD文件是描述信号波形的文件,采用ASCII码方式,每一位信号有变化了才记录下来值和时间点,完整的代码如下:
    for(i=0; i<nSampleSize; i++)
    {
    VCDString +="#";                //
    itoa(nEdgTime, strEdgTime, 32); //将采样时间点转换成字符串型
    VCDString +="\n";
    for (j=0; j<32; j++)
    {
    if(pbReadBuf[i][j]!=bPre[j] && bREG[j]==1)//不一致则处理
                                                          //bREG表示要处理哪些位
    {

    VCDString +=strEdgTime; //加上时间点
    bPre.flip(j);           //不一致则取反      
    itoa((int)(bPre[j]), strVar, 2);//转换成字符型
    VCDString +=(CString)strVar;    
    VCDString +=(CString)cVecChannel[j];
    }
    }
    bPre=pbReadBuf[i];      //保存上一次的采样点
    nEdgTime +=nSampleRate;//采样间隔是nSampleRate==25ns,
    }
    要做的就是分析这1100000个采样点,pbReadBuf是bitset<32>型数据(这里我就当成32位UINT型来看了),来自采样缓冲区,缓冲区深度是32bitX11000000,bPre也是bitset<32>,用来保存上一个采样点,里面嵌套的for 32循环,是分析每个pbReadBuf[i]的位[j],如果位[j]和上一个采样点的位[j]不一样,则将其取反,并生成字符型给VCDString,VCDString是最终写到VCD文件里面的CString型变量。
      

  10.   

    ModelSim软件也可以生成VCD文件,它那个也很快啊,采样点再多,比如十几亿个,不过几分钟而已。
      

  11.   

    1.源代码里用了CString的+,而且一直在+,需要好多好多内存...,换成一个足够大的buff,满了就写到文件里,可以异步。
    2.你先转了时间字串在判断条件,其实很多时间转换后面不会用到,换一下顺序。
      

  12.   

    楼上正解,现在修改了一下,只要不到一分钟了
    for(i=nSampleSize; i>0; i--)
    {
    if(*(pbReadBuf+nSampleSize-i)!=bPre)
    {
    VCDString +="#";
    itoa(nEdgTime, strEdgTime, 10);
    VCDString +=strEdgTime;
    VCDString +="\n";
    for(j=32; j>0; j--)
    {
    if((*(pbReadBuf+nSampleSize-i))[j-1]!=bPre[j-1] && bREG[j-1]==1)
    {

    bPre.flip(j-1);
    itoa((int)(bPre[j-1]), strVar, 2);
    VCDString +=(CString)strVar;
    VCDString +=(CString)cVecChannel[j-1];
    }
    }
    }
    bPre=*(pbReadBuf+nSampleSize-i);
    nEdgTime +=nSampleRate;
    }但是新的问题出来了,获得的VCDString没有多少个字符,但是能单步到
    if((*(pbReadBuf+nSampleSize-i))[j-1]!=bPre[j-1] && bREG[j-1]==1)里面很多很多次,查看VCDString变量,怎么一直没有变化啊,是不是CString使用出问题了,看MSDN,说“+=”操作要防内存溢出,但是我运行的时候没出现这个问题,就是VCDString没有递增了,还得恳请大家再帮忙看看,网上也搜了一下CString 的使用,说的不清,照着做了也木效果
      

  13.   

    另用VCDString.Getlength()发现长度还是在递增的,为什么就是没有东西呢
      

  14.   

    CString += 换成 Append() 试试看有没有效果
      

  15.   

    14楼的代码跟17楼的代码所实现的功能完全不同。所以实在不知道你到底打算做什么了。要想速度快,很简单,不要使用CString、string等任何一种预先做好的字符串类型,直接使用char *。同时也不要使用任何strcat之类的字符串函数——就是说除了itoa,这段代码里不要使用任何一个函数,只要做到了这些,你的这段代码可以很容易达到十几亿个采样点只需几分钟。
      

  16.   

    尽量在大量循环中不要使用库函数,itoa倒不如自写了个人感觉