0

我有这样的事情:

using (SqlDataAdapter a = new SqlDataAdapter(query, c))
            {
                // 3
                // Use DataAdapter to fill DataTable
                DataTable t = new DataTable();
                a.Fill(t);

                string txt = "";
                for (int i = 0; i < t.Rows.Count; i++)
                {
                    txt += "\n" + t.Rows[i][0] + "\t" + t.Rows[i][1] + "\t" + t.Rows[i][2] + "\t" + t.Rows[i][3] + "\t" + t.Rows[i][4] + "\t" + t.Rows[i][5] + "\t" + t.Rows[i][6] + "\t" + t.Rows[i][7] + "\t" + t.Rows[i][8] + "\t" + t.Rows[i][9] + "\t" + t.Rows[i][10] + "\t" + t.Rows[i][11] + "\t" + t.Rows[i][12] + "\t" + t.Rows[i][13] + "\t" + t.Rows[i][14] + "\t" + t.Rows[i][15] + "\t" + t.Rows[i][16] + "\t" + t.Rows[i][17] + "\t" + t.Rows[i][18] + "\t" + t.Rows[i][19];
                }


            }

我需要列之间的这个选项卡稍后生成 txt 文件。问题是 t.Rows.Count = 600000 并且这个循环工作 9 小时。任何想法如何使这更快?

问候卡兹克

4

4 回答 4

8

使用 aStringBuilder而不是连接你的字符串。

            string txt = "";
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < t.Rows.Count; i++)
            {
                sb.Append(t.Rows[i][0]); 
                sb.Append("\t");
                sb.Append(t.Rows[i][1]);
                //and so on...
           }
           string txt = sb.ToString();

将一个字符串添加到另一个字符串(通过再次分配它)相对于组合字符串的长度需要付出努力- 这对于大字符串来说非常昂贵 - 这是一个Schlemiel the Painter 的算法。使用 aStringBuilder可以避免这种情况,因为每次向其内容添加新字符串时都不必创建新字符串。

我不得不质疑为什么您将所有这些数据保存在内存中只是为了将其写入文件 - 您应该切换到允许您逐行生成文本内容的模型,我建议改用数据阅读器和产生文本行的方法,例如:

public IEnumerable<string> GenerateTextOutput()
{
   //...
   //using SqlDataReader instead
   while(reader.Read())
   {
     //assemble string for next row
     string txt = "...";
     yield return txt;
   }
}

然后您可以将此输出写入磁盘:

File.WriteAllLines("foo.txt", GenerateTextOutput());
于 2012-04-26T20:28:53.587 回答
4

使用字符串生成器。您可以在网络上随处找到示例。

于 2012-04-26T20:28:59.873 回答
2

其他人提到StringBuilder,他们是正确的。但是,请注意,在 .NET 4 中,StringBuilder 变得更加高效,完全避免了重新分配和内存复制。如果您使用的是 .NET 的早期版本,您将获得更差的性能。它仍然会打败你正在做的事情。

我想知道你txt准备好之后在做什么。您可能希望避免将字符串完全存储在内存中,并将其直接写入文件(我不相信您正在向用户展示 600,000 行......)

于 2012-04-26T20:37:15.093 回答
0

StringBuilder其他人已经提到过,应该会带来显着的好处。

真的需要将整个文本保存在 600K 行的内存中吗?您可以通过直接写入文件来加快速度。

对于这么多的迭代,将 Rows[i] 分配给一个变量也可能会提供一些额外的加速。

于 2012-04-26T20:33:43.210 回答