我有一个小项目,我已经为一个独立的学习班学习了一段时间。我应该导入大约140,000个数据点进行基于IDW的数学分析,目前程序需要大约10~14分钟来导入我的所有点。
我正在做的是读取.txt文件,基于新行拆分,然后根据字段之间的空格拆分未来。然后将它们转换为我设计的Datapt对象,以便于OOD风格操作。
所有我想知道的是,我可能不得不使用该程序进行现场演示,我不希望人们在预加载时必须坐在那里14分钟,如果推动我可以找到来自朋友的笔记本电脑(我的主要功能是dekstop)并在我的演示之前预先加载它,但整个问题让我想知道为什么加载只有100k数据片需要这么长时间?我想这会花费更短的时间?如果有比任何人都知道的更快的方式,如果你可以分享它,将不胜感激!
private void openPointsToolStripMenuItem_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "Text files|*.txt|All files|*.*";
openFileDialog1.Title = "Open the Captured Packets";
openFileDialog1.ShowDialog();
//Check to see if a filename was given
if (openFileDialog1.FileName != "")
{
readOut = System.IO.File.ReadAllText(openFileDialog1.FileName);
//textBox1.Text = System.IO.File.ReadAllText(openFileDialog1.FileName);
dataChain = readOut.Split(new String[] { "\r\n", "\n" }, StringSplitOptions.None);
//Read out Code
string[] link; //dataChain[0].Split(null);
for(int i = 0; i < 100000; i++)
{
link = dataChain[i].Split(null);
textBox1.AppendText(link[0] + " " + link[1] + " " + link[2] + " "+ link[3] + "\r\n");
dataPt Temp = new dataPt(Convert.ToDouble(link[0]), Convert.ToDouble(link[1]), Convert.ToDouble(link[2]), Convert.ToDouble(link[3]));
dataList.Add(Temp);
ptDisplay.Items.Add(Temp.ToString());
}
}
}
答案 0 :(得分:0)
我想到的一个改进是,您不需要将整个文件加载到内存中。您可以使用ReadLines
方法逐行处理它,该方法返回Enumerable<string>
,您可以使用Take
扩展方法进一步过滤结果:
private void openPointsToolStripMenuItem_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "Text files|*.txt|All files|*.*";
openFileDialog1.Title = "Open the Captured Packets";
openFileDialog1.ShowDialog();
if (openFileDialog1.FileName != "")
{
foreach (string line in System.IO.File.ReadLines(openFileDialog1.FileName).Take(100000))
{
var link = line.Split(null);
textBox1.AppendText(link[0] + " " + link[1] + " " + link[2] + " "+ link[3] + "\r\n");
dataPt Temp = new dataPt(Convert.ToDouble(link[0]), Convert.ToDouble(link[1]), Convert.ToDouble(link[2]), Convert.ToDouble(link[3]));
dataList.Add(Temp);
ptDisplay.Items.Add(Temp.ToString());
}
}
}
答案 1 :(得分:0)
不要一次将文本全部加载到内存中。而是使用内部循环中的File.ReadLines枚举行并逐个处理它们,但不更改每行的TextBox.Text也非常重要。这在执行和内存占用方面都非常昂贵。 (字符串是不可变的,所以在每个循环中,一个新的字符串在内存中分配,而前一个字符串就是内存碎片造成的破坏)
StringBuilder sb = new StringBuilder();
foreach(string line in File.ReadLines(openFileDialog1.FileName))
{
link = line.Split();
sb.AppendLine(link[0] + " " + link[1] + " " + link[2] + " "+ link[3]);
dataPt Temp = new dataPt(Convert.ToDouble(link[0]), Convert.ToDouble(link[1]), Convert.ToDouble(link[2]), Convert.ToDouble(link[3]));
dataList.Add(Temp);
ptDisplay.Items.Add(Temp.ToString());
}
textBox1.AppendText(sb.ToString());
而是将每一行添加到一个StringBuilder class,它比一个TextBox.Text属性更好地处理连接在一起的字符串。然后在退出循环时,只更改TextBox.Text一次。