请教诸位高手,下面的代码速度可否再有优化?      Stopwatch sw = new Stopwatch();
output("计算开始...");
sw.Start();
using (StreamReader sr = new StreamReader(tb_filepath.Text))
    {
        String line;
        while ((line = sr.ReadLine()) != null)
        {
           if (line.IndexOf(tb_keyword.Text) != -1) { count++; };
        }
        output("字符串出现次数:"+count.ToString());
    }
sw.Stop();
decimal micro = sw.Elapsed.Ticks / 10000000m;
output("计算结束");
output("花费时间:"+micro.ToString()+" s");

解决方案 »

  1.   

    把大文件还有C++以及你C#的时间,查询的字符串都发过来
    最好还有C++的程序,我们看一下差别多大
      

  2.   

    优化余地不大,line这个变量有点多余
    不知道用Unsafe代码有没有用?
      

  3.   

    Unsafe代码
    用stackalloc语句在堆栈上分配合适大小的(具体大小与具体系统有关)缓冲区(byte数组)
    用FileStream打开文件,直接读到缓冲区
    在缓冲区中以指针移动位置,判断字符编码
      

  4.   

    “大文件”是一个200多MB的IIS日志文件,当然还有更大的日志文件,上G的,我只是拿最小的一个测试。需要判断字符串“index.shtml”出现的次数同事用的是C++文件指针,每次读一行,然后判断这一行中有无出现该字符串。c++程序运行时内存只占用2兆左右,不变化,cpu占用较高,硬盘灯长亮。c#程序运行时占用内存20兆左右,也不变化,cpu占用较高,硬盘灯快速闪亮。我怀疑是不是 StreamReader.ReadLine()返回String对象过程中 box unbox造成的?请高手指教把脉,谢谢!
      

  5.   

    字符串比较可以用int型指针,每次4个字节(64位系统可以用long型)
      

  6.   

    //我怀疑是不是 StreamReader.ReadLine()返回String对象过程中 box unbox造成的?
    根本不存在box unbox的问题
    楼主看一下我的回复
      

  7.   

    用同步的话我的做法是一次性读出
    sr.ReadToEnd()
    然后在处理...
      

  8.   

    再说你这段代码的问题
    变量line没必要
    循环判断条件改为StreamReader.Peek()不是-1
    循环体内直接使用ReadLine().IndexOf
      

  9.   

    同样的功能...同样的代码C#效率肯定不如C++,C++肯定不如C,C肯定不如汇编...地球人都知道的事情...还是那句话,如果你能精通C++,不至于堕落到学C#
      

  10.   

    Mark.相信C#不会输给C++.
    从硬盘灯的情况看,应该是读文件的性能没跟上.试试其它几个读文件的类,或者是流的类.
    或者测一下IndexOf方法的性能.
      

  11.   

    我以前的同事,用C/C++(Unix)8年,Windos上的VC也相当熟悉,后来工作需要,也"堕落"到用C#,难道不可以吗?
      

  12.   

    to shrinerain(圣影雨)Knight94(愚翁)知道吗,据我观察,他对C++也是相当熟悉的
    不也是"堕落"到C#了?
      

  13.   

    编程不是搞宗教,非要拿个工具来崇拜爱用啥用啥C#慢,我可以调你C++写的DLL吧?编程目的是:
    尽量把繁琐的事情交给机器处理
    而不是把繁琐的事情留给自己//回到楼主的问题
    直接调用API
    OpenFile()
    ReadFile()
    分块来读取文件,估计会快一些
      

  14.   

    呵呵~~
    的确我偏激了一点...
    因为任何事情都不是绝对的,我说的只是绝大多数情况.特别是针对CSDN...
    --------------------------------------------------------------------另外,我其实工作内容主要是在UNIX平台下,工作语言C和Shell,但平时我更多用C#.
    我同事也是这样,他应该是精通C级别的人,不过他写些小软件也是用C#,没办法,做界面C#太方便了.
      

  15.   

    为 tb_keyword.Text 定义一个临时变量,会快一些。
      

  16.   

    就算C#慢,也不会慢5倍吧。LZ的程序可以优化一下,不要用 ReadLine 和 Indexof , 自己处理文件,读一片缓冲区查找一片,用KMP算法进行匹配。
    还有用unsafe代码,把缓冲区fix住
      

  17.   

    谢谢大家!
    说一下最新进展吧。感谢“viena(维也纳nn-收回潜望镜,下潜50米)”,但是因为我没有Unsafe代码经验,暂时还没入手,不过肯定是要尝试一下的。我把LINE变量去掉了,速度提升了1-2秒,原来的速度是25秒左右。接下来要感谢的是“y1g1y1(袁飞☆VB诚可贵VB.Net价更高C#心中有二者皆可抛☆) ”,
    ------tb_keyword.Text 定义一个临时变量这种方法竟然提速一倍!!大约在14秒就完成了查找!
      

  18.   

    应该不会有5倍的差别再试试 unsafe
      

  19.   

    还有如果用Unsafe代码
    字符串比较,如果用指针,恐怕没我说的那么简单
    如runrunrun(做最好的自己)所说,恐怕要用KMP之类的算法进行匹配
      

  20.   

    to 我的C#代码比同事的C++慢5倍左右你的开发速度比C++快10倍左右
      

  21.   

    .NET类库的代码与Java类似,都是经过层层调用,为了代码安全性中间有很多判断,执行效率肯定会大打折扣的,你反编译一下CLR就知道了~
      

  22.   

    最新进展!!!!!!!!!!!!!!!!!!关键代码改为:
    if (sr.ReadLine().IndexOf(keyword,StringComparison.Ordinal) != -1) { count++; };
    后,低于7秒了!!虽然跟C++的5秒左右仍有区别,但是不大了,谢谢大家奥