C# 提高streamwriter在c中的性能#
在我的程序中,我需要编写大型文本文件(~300 mb),文本文件包含以空格分隔的数字,我使用以下代码:C# 提高streamwriter在c中的性能#,c#,multithreading,thread-safety,streamreader,streamwriter,C#,Multithreading,Thread Safety,Streamreader,Streamwriter,在我的程序中,我需要编写大型文本文件(~300 mb),文本文件包含以空格分隔的数字,我使用以下代码: TextWriter guessesWriter = TextWriter.Synchronized(new StreamWriter("guesses.txt")); private void QueueStart() { while (true) { if (writeQueue.Count > 0)
TextWriter guessesWriter = TextWriter.Synchronized(new StreamWriter("guesses.txt"));
private void QueueStart()
{
while (true)
{
if (writeQueue.Count > 0)
{
guessesWriter.WriteLine(writeQueue[0]);
writeQueue.Remove(writeQueue[0]);
}
}
}
private static void Check()
{
TextReader tr = new StreamReader("data.txt");
string guess = tr.ReadLine();
b = 0;
List<Thread> threads = new List<Thread>();
while (guess != null) // Reading each row and analyze it
{
string[] guessNumbers = guess.Split(' ');
List<int> numbers = new List<int>();
foreach (string s in guessNumbers) // Converting each guess to a list of numbers
numbers.Add(int.Parse(s));
threads.Add(new Thread(GuessCheck));
threads[b].Start(numbers);
b++;
guess = tr.ReadLine();
}
}
private static void GuessCheck(object listNums)
{
List<int> numbers = (List<int>) listNums;
if (!CloseNumbersCheck(numbers))
{
writeQueue.Add(numbers[0] + " " + numbers[1] + " " + numbers[2] + " " + numbers[3] + " " + numbers[4] + " " + numbers[5] + " " + numbers[6]);
}
}
private static bool CloseNumbersCheck(List<int> numbers)
{
int divideResult = numbers[0]/10;
for (int i = 1; i < 6; i++)
{
if (numbers[i]/10 != divideResult)
return false;
}
return true;
}
我知道这不是很有效,我一直在寻找一些建议,如何使它更快。
如果您知道如何比.txt更有效地保存大量数字,我将不胜感激。使用BinaryWriter可以提高效率。然后你可以直接写出整数。这将允许您跳过读取时的解析步骤和写入时的ToString转换 看起来你也在那里创建了一堆线程。额外的线程会降低性能。您应该在单个线程上完成所有工作,因为线程是非常重的对象 下面是代码使用BinaryWriter的直接转换。(这并不能解决线程问题。)
BinaryWriter guesswriter=newbinarywriter(newstreamwriter(“guesss.dat”);
私有void QueueStart()
{
while(true)
{
如果(writeQueue.Count>0)
{
锁(猜写器)
{
GuessWriter.Write(writeQueue[0]);
}
writeQueue.Remove(writeQueue[0]);
}
}
}
私有常量int numbersPerThread=6;
私有静态无效检查()
{
BinaryReader tr=新的BinaryReader(新的StreamReader(“data.txt”);
b=0;
列表线程=新列表();
while(tr.BaseStream.Position
尝试在两者之间使用缓冲区。这里有一股低潮。现在,您使用的磁盘访问模式非常低效。您应该读写大数据块(读块和写块),而不是逐行读写(读线和写线)。这样一来,您访问磁盘的次数将大大减少,性能也将大大提高。但是您需要管理每一行的结尾(查看Environment.NewLine)。提高效率的一种方法是在输出流上使用更大的缓冲区。您使用的是默认值,这可能会给您一个1k的缓冲区,但如果缓冲区少于64k,您将看不到最大性能。按如下方式打开文件:
new StreamWriter("guesses.txt", new UTF8Encoding(false, true), 65536)
writeQueue是什么类型的对象?TextWriter.Synchronized()似乎没有用,因为您只能从一个线程(QueueStart())访问文件。但是您的队列或列表“writeQueue”应该是同步的,如果不是的话。writeQueue是一个列表,我将缓冲区大小增加到64k(感谢Gabe),我将其全部添加到一个线程中(感谢Jeffery),这样做会更快。该程序用于剪切彩票号码,而不是pin码……我尝试使用binarywriter,但构造函数需要一个流,我无法从应用程序的主窗体访问流构造函数,我是否遗漏了什么?@Ofir-我在回答中添加了一些代码。我不知道你为什么不能访问流构造函数。它与BinaryReader本身位于同一名称空间中。我现在明白了,我没有正确使用它。谢谢,现在快多了。我不明白你的答案
BinaryWriter
没有采用StreamWriter
的构造函数。
BinaryWriter guessesWriter = new BinaryWriter(new StreamWriter("guesses.dat"));
private void QueueStart()
{
while (true)
{
if (writeQueue.Count > 0)
{
lock (guessesWriter)
{
guessesWriter.Write(writeQueue[0]);
}
writeQueue.Remove(writeQueue[0]);
}
}
}
private const int numbersPerThread = 6;
private static void Check()
{
BinaryReader tr = new BinaryReader(new StreamReader("data.txt"));
b = 0;
List<Thread> threads = new List<Thread>();
while (tr.BaseStream.Position < tr.BaseStream.Length)
{
List<int> numbers = new List<int>(numbersPerThread);
for (int index = 0; index < numbersPerThread; index++)
{
numbers.Add(tr.ReadInt32());
}
threads.Add(new Thread(GuessCheck));
threads[b].Start(numbers);
b++;
}
}
new StreamWriter("guesses.txt", new UTF8Encoding(false, true), 65536)