我有这样的事情:
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];
}
}
Run Code Online (Sandbox Code Playgroud)
我需要在列之间使用此选项卡以便稍后生成txt文件.问题是t.Rows.Count = 600000,这个循环工作9个小时.任何想法如何使这更快?
关心kazik
使用StringBuilder而不是连接字符串.
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();
Run Code Online (Sandbox Code Playgroud)
将一个字符串添加到另一个字符串(通过再次分配它)需要相对于组合字符串的长度- 这对于大字符串来说非常昂贵 - 这是Schlemiel the Painter的算法.使用a StringBuilder避免这种情况,因为每次向其内容添加新字符串时都不必创建新字符串.
我不得不质疑为什么你把所有这些数据保存在内存中只是为了把它写到文件中 - 你应该切换到一个允许你逐行生成文本内容的模型,我建议使用数据读取器代替和产生文本行的方法,例如:
public IEnumerable<string> GenerateTextOutput()
{
//...
//using SqlDataReader instead
while(reader.Read())
{
//assemble string for next row
string txt = "...";
yield return txt;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以把这个输出写到磁盘:
File.WriteAllLines("foo.txt", GenerateTextOutput());
Run Code Online (Sandbox Code Playgroud)