直接上代码,现在用时大约在2分钟以上static void ParseTxt()
        {
            /*
             * a.txt 数据
             * 操作系统确定程序是否成功执行完毕
             * 函数体函数定义的最后部分
             * 程序编写完后需要进行编译
             * 标准库定义了 4 个 IO 对象
             * 系统将这些对象与执行程序的窗口联系起来
             * 编译器要使用库
             * 
             * b.txt 数据
             * 讲解
             * 函数部分
             * 程序编译
             * 标准库对象
             * 系统窗口
             * 编译器讲解
             * 
             * 解析后新生成的newa.txt应该是这样的
             * 操作系统确定程序是否成功执行完毕   【未找到】
             * 函数体函数定义的最后部分 体函数定义的最后部分
             * 程序编写完后需要进行编译 编写完后需要进行编译
             * 标准库定义了 4 个 IO 对象    定义了 4 个 IO 对象
             * 系统将这些对象与执行程序的窗口联系起来   将这些对象与执行程序的窗口联系起来
             * 编译器要使用库   要使用库
             */
            string aPath = "a.txt";//16W+数据
            string bPath = "b.txt";//2000+数据
            string newaPath = "newa.txt";//与a.txt数据量相同
            string[] arrA = File.ReadAllLines(aPath);
            string[] arrB = File.ReadAllLines(bPath);
            StringBuilder sb = new StringBuilder();
            bool isHave = false;
            string titleTrim = string.Empty;
            string subTitle = string.Empty;
            char[] sChar = new char[] { ' ', '[', '[', '(', '『', '(', '{', '【' };
            char[] eChar = new char[] { ' ', ']', '+', '/', '』', ']', ')', '-', '}', '】' };
            foreach (string title in arrA)
            {
                titleTrim = title.TrimStart(sChar);
                for (int i = 2; i < titleTrim.Length; i++)
                {
                    isHave = false;
                    subTitle = titleTrim.Substring(0, i);
                    foreach (string b in arrB)
                    {
                        if (b.Contains(subTitle))
                        {
                            isHave = true;
                            break;
                        }
                    }
                    if (!isHave)
                    {
                        if (i == 2)
                        {
                            sb.Append(title + "\t【未找到】\r\n");
                        }
                        else
                        {
                            sb.Append(title + "\t" + titleTrim.Substring(i - 1, titleTrim.Length - i + 1).TrimStart(eChar) + "\r\n");
                        }
                        break;
                    }
                }
            }
            File.WriteAllText(newaPath, sb.ToString());
        }

解决方案 »

  1.   

    File.WriteAllText(newaPath, sb.ToString());
    好像在循环内部,你考虑把它移到外部行不行,这个应该很占时间的,IO操纵很费时
      

  2.   

    用Linq试了没?
    多长时间?
      

  3.   


    Linq没试,不会Linq,.net2.0下
    或者用C++是否会提高效率?
      

  4.   

    毕竟数据量在那呢,估计速度再快也快不起来。不过你可不可以试着分批操作呢?
    将数据量较大的txt分成多个操作。
      

  5.   

    大致看了一下代码,似乎是在B中查找A中的串,然后把匹配的结果存入C。期间要把A的左右括号去掉。我在想,利用正则表达式Regex.Replace(),是不是会好一些?这比你反复地取用同一个串,在B中进行遍历应该会效率许多。其中每次查找的Regex,根据A中单词的不同进行动态构造,然后在B中进行Replace。具体的我还没细想。
      

  6.   

    我觉得是:
    subTitle = titleTrim.Substring(0, i);
    foreach (string b in arrB)
    {
       if (b.Contains(subTitle))
       {
         isHave = true;
         break;
       }
    }
    这里最浪费时间,要优化
      

  7.   


    我想过把据量较大的txt分成10个,然后分10条线程操作,理论上会快10倍?
    那样的话多线程要传参并且有返回值,不太好弄啊。
      

  8.   

    现在要30秒+了
    正则表达式不知道写合适,就想着怎么优化(好昵称都被占用了) 说的那段代码,我是这么优化的,就是把arrB换成了string b static void ParseTxt()
            {
                   string aPath = "a.txt";//16W+数据
                string bPath = "b.txt";//2000+数据
                string newaPath = "newa.txt";//与a.txt数据量相同
                string[] arrA = File.ReadAllLines(aPath);
                string b = File.ReadAllText(bPath);
                StringBuilder sb = new StringBuilder();
                bool isHave = false;
                string titleTrim = string.Empty;
                string subTitle = string.Empty;
                char[] sChar = new char[] { ' ', '[', '[', '(', '『', '(', '{', '【' };
                char[] eChar = new char[] { ' ', ']', '+', '/', '』', ']', ')', '-', '}', '】' };
                foreach (string title in arrA)
                {
                    titleTrim = title.TrimStart(sChar);
                    for (int i = 2; i < titleTrim.Length; i++)
                    {
                        isHave = false;
                        subTitle = titleTrim.Substring(0, i);
                        if (b.Contains(subTitle))
                        {
                            isHave = true;
                        }
                        if (!isHave)
                        {
                            if (i == 2)
                            {
                                sb.Append(title + "\t【未找到】\r\n");
                            }
                            else
                            {
                                sb.Append(title + "\t" + titleTrim.Substring(i - 1, titleTrim.Length - i + 1).TrimStart(eChar) + "\r\n");
                            }
                            break;
                        }
                    }
                }
                File.WriteAllText(newaPath, sb.ToString());
            }
      

  9.   

    就你目前的这个方法,如果想提高效率,可以使用多线程。
    string[] arrA = File.ReadAllLines(aPath);这个数据比较大(16W+),建立10个线程,
    每一个线程读取16000的数据,每个线程里的arrB(2000)都是全部数据,
    这样处理的话,初步估计在30秒内可以完成
      

  10.   

    这种情况尤其是在多核cpu的服务器上,效果会比较明显。
      

  11.   

    感觉还是太长了
    你可以看一下notepad这个软件,开源的,
    它打开8M左右的txt文件只要2秒左右,
    用的是多线程,还有内存映射文件技术,
    你用上了估计能减少到5秒以内
      

  12.   

    又修改了下,在我这双核上只能跑到20S左右,在I7上只要2S左右了,差距太大了。代码有点乱class Test
        {
            private delegate string FuncHandle(string[] arrA, string b);
            //调用方法
            public void ParseTxt()
            {
                string aPath = "a.txt";//16W+数据
                string bPath = "b.txt";//2000+数据
                string newaPath = "newa.txt";//与a.txt数据量相同
                string[] arrA = File.ReadAllLines(aPath);
                string b = File.ReadAllText(bPath);
                int threadCount = 10;
                string[][] a = SplitArray(arrA, threadCount);
                StringBuilder sbb = new StringBuilder();
                FuncHandle[] fhs = new FuncHandle[threadCount];
                IAsyncResult[] ars = new IAsyncResult[threadCount];
                for (int i = 0; i < threadCount; i++)
                {
                    fhs[i] = new FuncHandle(this.ParseThreadMethod);
                    ars[i] = fhs[i].BeginInvoke(a[i], b, null, null);
                }
                for (int j = 0; j < threadCount; j++)
                {
                    ars[j].AsyncWaitHandle.WaitOne();
                    sbb.Append(fhs[j].EndInvoke(ars[j]));
                }
                File.WriteAllText(newaPath, sbb.ToString());
            }
            //处理方法
            private string ParseThreadMethod(string[] arrA, string b)
            {
                StringBuilder sb = new StringBuilder();
                string subTitle = string.Empty;
                bool isHave = false;
                string titleTrim = string.Empty;
                char[] sChar = new char[] { ' ', '[', '[', '(', '『', '(', '{', '【' };
                char[] eChar = new char[] { ' ', ']', '+', '/', '』', ']', ')', '-', '}', '】' };
                foreach (string title in arrA)
                {
                    titleTrim = title.TrimStart(sChar);                for (int i = 2; i < titleTrim.Length; i++)
                    {
                        isHave = false;
                        subTitle = titleTrim.Substring(0, i);
                        if (b.Contains(subTitle))
                        {
                            isHave = true;
                        }
                        if (!isHave)
                        {
                            if (i == 2)
                            {
                                sb.Append(title + "\t【未找到】\r\n");
                            }
                            else
                            {
                                sb.Append(title + "\t" + titleTrim.Substring(i - 1, titleTrim.Length - i + 1).TrimStart(eChar) + "\r\n");
                            }
                            break;
                        }
                    }
                }
                return sb.ToString();
            }
            //数组拆分
            private string[][] SplitArray(string[] arr, int splitCount)
            {
                int arrLength = arr.Length;
                int newArrLenth = arrLength / splitCount;
                string[][] reArr = new string[splitCount][];
                string[] tempArr;
                int tempArrIndex = 0;
                for (int j = 0; j < splitCount; j++)
                {
                    tempArrIndex = 0;
                    if (j == splitCount - 1)
                    {
                        tempArr = new string[arrLength - newArrLenth * (splitCount - 1)];
                    }
                    else
                    {
                        tempArr = new string[newArrLenth];
                    }
                    for (int i = j * newArrLenth; i < arr.Length; i++)
                    {
                        tempArr[tempArrIndex] = arr[i];
                        if (j != splitCount - 1 && tempArrIndex == newArrLenth - 1)
                            break;
                        tempArrIndex++;
                    }
                    reArr[j] = tempArr;
                }
                return reArr;
            }
        }
      

  13.   

                string[] arrA = File.ReadAllLines(aPath);
                string[] arrB = File.ReadAllLines(bPath);
     不用数组,这个查找效率O(n),改为HashSet存储字符串值再查找比较,内部采用hash算法比较时间为O(1),改为这两个数据结构,应该会快蛮多。你测试看看
      

  14.   


    读盘速度 用不用多线程都一样的。。
    先一次txt映射到内存在处理。。