专家的一些帮助。我试图使用下面的函数将字符串打印到文件中。当我使用Console.Write()或Console.WriteLine()时,输出文件每秒增长3MB或4MB,但当我尝试以下面所示的方式使用StreamWriter或File.AppendAllText输出时,文件只会在每秒20KB或30KB。
当我使用StreamWriter而不是Console.WriteLine()时,为什么打印速度会降低太多? 我应该使用什么方法写入保持与Console.WriteLine()相同速度的文件?
public static void PrintFunction()
{
//using (StreamWriter writer = File.AppendText(@"C:\OuputFile.txt"))
using (StreamWriter writer = new StreamWriter(@"C:\OuputFile.txt", true))
{
//Console.Write("This is "); // Print speed is about 3MB-4MB per second
writer.Write("This is "); //Print decreases to 20KB-30KB per second
//File.AppendAllText(@"C:\OuputFile.txt", "This is "); Print decreases to 20KB-30KB per second
// SOME CODE
// SOME CODE
//Console.WriteLine("the first line"); // Print speed is about 3MB-4MB per second
writer.WriteLine("the first line"); // Print decreases to 20KB-30KB per second
//File.AppendAllText(@"C:\OuputFile.txt", "the first line"); // Print decreases to 20KB-30KB per second
}
}
更新 当我说我使用Console.WriteLine()时,我的意思是,我在代码中使用了Console.WriteLine(),但为了将这些打印保存在文件中,我重定向输出就像这样:
MyProgram.exe inputfile > outputfile.txt
我知道内存和硬盘的区别,但是为什么当我使用Console.WriteLine()重定向输出如上所述(打印到硬盘)时,打印速度比使用StreamWriter快1000多倍?
我尝试过如下增加缓冲区大小,但打印速度并没有增长。
using (StreamWriter writer = new StreamWriter(@"C:\OuputFile.txt", true, Encoding.UTF8, 65536))
更新2:
大家好,感谢所有的帮助,你是最好的!!!根据您的所有建议和示例,我在外面定义了StreamWriter PrintFunction和这次只调用一次编写器进程,输出文件保持打开状态直到结束并以这种方式 打印过程速度与Console.WrileLine()相同。
我已经通过作者作为函数的参数,如下所示,它的工作原理。我已经测试过缓冲区大小为4KB,64KB和 默认值如下所示,当我设置明确使用的4096字节缓冲区时,结果更快。该函数被调用 略多于1000万次,输出文件为670 MB。
*StreamWriter(@"C:\OuputFile.txt", true, Encoding.UTF8, 4096) --> 660845.1181 ms --> 11.0140853 min
StreamWriter(@"C:\OuputFile.txt", true, Encoding.UTF8, 65536) --> 675755.0119 ms --> 11.2625835 min
StreamWriter(@"C:\OuputFile.txt") --> 712830.3706 ms --> 11.8805061 min*
再次感谢您的帮助。
此致
代码如下所示:
public static void ProcessFunction()
{
StreamWriter writer = new StreamWriter(@"C:\OuputFile.txt", true, Encoding.UTF8, 4096);
while ( condition)
{
PrintFunction(writer);
}
if( writer != null )
{
writer.Dispose();
writer.Close();
}
}
public static void PrintFunction(StreamWriter writer)
{
//SOME CODE
writer.Write("Some string...");
//SOME CODE
}
答案 0 :(得分:4)
我对此进行了描述,看起来完全相反。我能够将.25GB / s写入标准的10K rpm驱动器(无SSD)。看起来你经常调用这个函数并且每次都通过连接它来写入文件。尝试这样的事情(我从一个旧的控制台日志代码中迅速将其剪切在一起,因此它可能有点错误,并且错误处理肯定不完整):
public static class LogWriter
{
// we keep a static reference to the StreamWriter so the stream stays open
// this could be closed when not needed, but each open() takes resources
private static StreamWriter writer = null;
private static string LogFilePath = null;
public static void Init(string FilePath)
{
LogFilePath = FilePath;
}
public static void WriteLine(string LogText)
{
// create a writer if one does not exist
if(writer==null)
{
writer = new StreamWriter(File.Open(LogFilePath,FileMode.OpenOrCreate,FileAccess.Write,FileShare.ReadWrite));
}
try
{
// do the actual work
writer.WriteLine(LogText);
}
catch (Exception ex)
{
// very simplified exception logic... Might want to expand this
if(writer!=null)
{
writer.Dispose();
}
}
}
// Make sure you call this before you end
public static void Close()
{
if(writer!=null)
{
writer.Dispose();
writer = null;
}
}
}
答案 1 :(得分:1)
当我使用StreamWriter而不是Console.WriteLine()时,为什么打印速度会降低太多?
当您将命令输出重定向到文件时,无论您使用console.Write()
调用PrintFunction()多少次,cmd.exe都会立即获取输出文件的只写访问权限。如果在PrintFunction()中使用流编写器,则每次都初始化编写器,尝试访问该文件,写入一行然后释放文件句柄。开销会影响性能。
我应该使用什么方法写入保持与Console.WriteLine()速度相同的文件?
您可以尝试以下其中一项