gpt4 book ai didi

c# - 将大量行写入文本文件的有效方法

转载 作者:太空狗 更新时间:2023-10-29 21:22:54 30 4
gpt4 key购买 nike

我开始做如下事情:

using (TextWriter textWriter = new StreamWriter(filePath, append))
{
foreach (MyClassA myClassA in myClassAs)
{
textWriter.WriteLine(myIO.GetCharArray(myClassA));

if (myClassA.MyClassBs != null)
myClassA.MyClassBs.ToList()
.ForEach(myClassB =>
textWriter.WriteLine(myIO.GetCharArray((myClassB)));

if (myClassA.MyClassCs != null)
myClassA.MyClassCs.ToList()
.ForEach(myClassC =>
textWriter.WriteLine(myIO.GetCharArray(myClassC)));
}
}

这看起来很慢(35,000 行大约需要 35 秒)。

然后我试着按照这个例子here用下面的代码创建一个缓冲区,但它并没有给我带来任何好处。我仍然看到大约 35 秒的时间。我实现缓冲区的方式是否有错误?

using (TextWriter textWriter = new StreamWriter(filePath, append))
{
char[] newLineChars = Environment.NewLine.ToCharArray();
//Chunk through 10 lines at a time.
int bufferSize = 500 * (RECORD_SIZE + newLineChars.Count());
char[] buffer = new char[bufferSize];
int recordLineSize = RECORD_SIZE + newLineChars.Count();
int bufferIndex = 0;

foreach (MyClassA myClassA in myClassAs)
{
IEnumerable<IMyClass> myClasses =
new List<IMyClass> { myClassA }
.Union(myClassA.MyClassBs)
.Union(myClassA.MyClassCs);

foreach (IMyClass myClass in myClasses)
{
Array.Copy(myIO.GetCharArray(myClass).Concat(newLineChars).ToArray(),
0, buffer, bufferIndex, recordLineSize);

bufferIndex += recordLineSize;

if (bufferIndex >= bufferSize)
{
textWriter.Write(buffer);

bufferIndex = 0;
}
}
}

if (bufferIndex > 0)
textWriter.Write(buffer);
}

有没有更好的方法来完成这个?

最佳答案

我强烈怀疑你的大部分时间都没有花在 I/O 上。写 35,000 行不可能需要 35 秒,除非这些行真的很长。

最有可能的是,大部分时间花在 GetCharArray 方法上,无论它做什么。

一些建议:

如果您真的认为 I/O 是问题所在,请增加流的缓冲区大小。调用StreamWriter constructor可以让您指定缓冲区大小。例如,

using (TextWriter textWriter = new StreamWriter(filePath, append, Encoding.Utf8, 65536))

这将比默认的 4K 缓冲区大小表现更好。缓冲区大小高于 64K 通常没有用,实际上会降低性能。

不要预先缓冲行或附加到 StringBuilder。这可能会给您带来小幅性能提升,但会以复杂性为代价。小小的性能提升不值得维护噩梦。

利用foreach。你有这个代码:

if (myClassA.MyClassBs != null)
myClassA.MyClassBs.ToList()
.ForEach(myClassB =>
textWriter.WriteLine(myIO.GetCharArray((myClassB)));

这必须从任何 MyClassBs 集合创建一个具体列表,然后枚举它。为什么不直接枚举一下:

if (myClassA.MyClassBs != null)
{
foreach (var myClassB in myClassA.MyClassBs)
{
textWriter.WriteLine(myIO.GetCharArray((myClassB)));
}
}

这将为您节省 ToList 所需的内存,以及在创建列表时枚举集合所需的时间。

综上所述,几乎可以肯定您的 GetCharArray 方法是一直占用时间的东西。如果你真的想加速你的程序,看看那里。尝试优化对 StreamWriter 的写入是浪费时间。你不会在那里获得显着的性能提升。

关于c# - 将大量行写入文本文件的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17325370/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com