c# - 文本重新格式化随着每次迭代而逐渐变慢

标签 c# string loops stringbuilder

编辑2

好的,我已经在gist.github上发布了源代码的副本,但只有一个无法解决的问题。

FindLine()始终返回-1。我将原因缩小为if语句,但是我不知道为什么。我知道symbol和symbolList都可以传递良好的数据。

/编辑2

我有一个相当简单的C#程序,该程序查找.csv文件,读取该文件中的文本,将其重新格式化(并包括加载到DataTable中的SQL查询中的一些信息),然后将其保存到.tsv文件中,以备后用通过另一个程序。

我的问题是,有时源.csv文件超过10,000行,并且该程序在遍历各行时逐渐变慢。如果.csv文件为〜500行,则大约需要45秒才能完成,随着.csv文件变大,这一次将成倍恶化。

SQL查询返回37,000+行,但只被请求一次,并且以.csv文件的相同方式进行排序,因此通常我不会注意到它遍历该文件,除非它找不到相应的数据,在这种情况下它会一直执行并返回适当的错误文本。我有99%的把握不是造成减速的原因。

y和z for循环的长度必须完全一样。

如果绝对必要,我可以从初始的.csv文件中清除一些数据并发布示例,但我真的希望我只是缺少真正明显的东西。

在此先感谢大家!

这是我的资料来源:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;

namespace MoxySectorFormatter
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable resultTable = new DataTable();
            double curLine = 1;
            double numLines = 0;
            string ExportPath = @"***PATH***\***OUTFILE***.tsv";
            string ImportPath = @"***PATH***\***INFILE***.csv";
            string NewText = "SECURITY\r\n";
            string OrigText = "";
            string QueryString = "SELECT DISTINCT UPPER(MP.Symbol) AS Symbol, LOWER(MP.SecType) AS SecType, MBI.Status FROM MoxySecMaster AS MP LEFT JOIN MoxyBondInfo AS MBI ON MP.Symbol = MBI.Symbol AND MP.SecType = MBI.SecType WHERE MP.SecType <> 'caus' AND MP.SecType IS NOT NULL AND MP.Symbol IS NOT NULL ORDER BY Symbol ASC;";
            SqlConnection MoxyConn = new SqlConnection("server=***;database=***;user id=***;password=***");
            SqlDataAdapter adapter = new SqlDataAdapter(QueryString, MoxyConn);

            MoxyConn.Open();
            Console.Write("Importing source file from \"{0}\".", ImportPath);
            OrigText = File.ReadAllText(ImportPath);
            OrigText = OrigText.Substring(OrigText.IndexOf("\r\n", 0) + 2);
            Console.WriteLine("\rImporting source file from \"{0}\".  Done!", ImportPath);
            Console.Write("Scanning source report.");
            for (int loop = 0; loop < OrigText.Length; loop++)
            {
                if (OrigText[loop] == '\r')
                    numLines++;
            }
            Console.WriteLine("\rScanning source report.  Done!");
            Console.Write("Downloading SecType information.");
            resultTable = new DataTable();
            adapter.Fill(resultTable);
            MoxyConn.Close();
            Console.WriteLine("\rDownloading SecType information.  Done!");

            for (int lcv = 0; lcv < numLines; lcv++)
            {
                int foundSpot = -1;
                int nextStart = 0;
                Console.Write("\rGenerating new file... {0} / {1} ({2}%)  ", curLine, numLines, System.Math.Round(((curLine / numLines) * 100), 2));
                for (int vcl = 0; vcl < resultTable.Rows.Count; vcl++)
                {
                    if (resultTable.Rows[vcl][0].ToString() == OrigText.Substring(0, OrigText.IndexOf(",", 0)).ToUpper() && resultTable.Rows[vcl][1].ToString().Length > 0)
                    {
                        foundSpot = vcl;
                        break;
                    }
                }
                if (foundSpot != -1 && foundSpot < resultTable.Rows.Count)
                {
                    NewText += resultTable.Rows[foundSpot][1].ToString();
                    NewText += "\t";
                    NewText += OrigText.Substring(nextStart, (OrigText.IndexOf(",", nextStart) - nextStart));
                    NewText += "\t";
                    nextStart = OrigText.IndexOf(",", nextStart) + 1;
                    for (int y = 0; y < 142; y++)
                        NewText += "\t";
                    if(resultTable.Rows[foundSpot][2].ToString() == "r")
                        NewText += @"PRE/ETM";
                    else if (OrigText.Substring(nextStart, (OrigText.IndexOf(",", nextStart) - nextStart)) == "Municipals")
                    {
                        NewText += "Muni - ";
                        nextStart = OrigText.IndexOf(",", nextStart) + 1;
                        if (OrigText.Substring(nextStart, (OrigText.IndexOf(",", nextStart) - nextStart)).Length > 0)
                            NewText += OrigText.Substring(nextStart, (OrigText.IndexOf(",", nextStart) - nextStart));
                        else
                            NewText += "(Orphan)";
                    }
                    else if (OrigText.Substring(nextStart, (OrigText.IndexOf(",", nextStart) - nextStart)) == "Corporates")
                    {
                        NewText += "Corporate - ";
                        nextStart = OrigText.IndexOf(",", nextStart) + 1;
                        nextStart = OrigText.IndexOf(",", nextStart) + 1;
                        if (OrigText.Substring(nextStart, (OrigText.IndexOf("\r\n", nextStart) - nextStart)).Length > 0)
                            NewText += OrigText.Substring(nextStart, (OrigText.IndexOf("\r\n", nextStart) - nextStart));
                        else
                            NewText += "(Unknown)";
                    }
                    else
                        NewText += OrigText.Substring(nextStart, (OrigText.IndexOf(",", nextStart) - nextStart));
                    for (int z = 0; z < 17; z++)
                        NewText += "\t";
                    NewText += "\r\n";
                    resultTable.Rows.RemoveAt(foundSpot);
                }
                else
                    Console.WriteLine("\r  Omitting {0}: Missing Symbol or SecType.", OrigText.Substring(nextStart, (OrigText.IndexOf(",", nextStart) - nextStart)));
                OrigText = OrigText.Substring(OrigText.IndexOf("\r\n", 0) + 2);
                curLine++;
            }
            Console.Write("Exporting file to \"{0}\".", ExportPath);
            File.WriteAllText(ExportPath, NewText);
            Console.WriteLine("\rExporting file to \"{0}\".  Done!\nPress any key to exit.", ExportPath);
            Console.ReadLine();
        }
    }
}

最佳答案

而不是使用+ =运算符进行串联,请使用System.Text.StringBuilder对象及其Append()和AppendLine方法

字符串在C#中是不可变的,因此,每次在循环中使用+ =时,都会在内存中创建一个新字符串,这可能会导致最终速度变慢。

关于c# - 文本重新格式化随着每次迭代而逐渐变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4962382/

相关文章:

c# - 每次构建时自定义 DataGridView 添加列

Java - 在 for 循环中使用 "continue"时出现未处理的异常错误?

python - 选择值与特定字符 python 匹配的行

android - 如何消除 Android 音频文件剪切之间的间隙

ruby - 如何打破 Ruby 中的嵌套循环?

java - While循环和switch

c# - 为什么 C# 不为集合实现 GetHashCode?

c# - 使用 OWIN 从解决方案中的 WPF 项目启动 asp.net WebApi 项目

c# - 访问其他内部硬盘

c - 字符串编辑器(无法正常工作)