2014-12-30 1 views
2

전문가의 도움을받습니다. 아래의 함수를 사용하여 문자열을 파일에 인쇄하려고합니다. Console.Write() 또는 Console.WriteLine()을 사용하면 출력 파일의 크기가 초당 3MB 또는 4MB 증가하지만 StreamWriter 또는 File.AppendAllText를 아래 표시된 방법으로 사용하려고하면 파일이 초당 20KB 또는 30KB.C#에서 파일에 문자열을 인쇄하도록 StreamWriter를 느리게하는 대체/더 빠른 방법

Console.WriteLine() 대신 StreamWriter를 사용하면 인쇄 속도가 너무 느려지는 이유는 무엇입니까? 동일한 속도의 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()를 나 '코드 내부하지만 파일에 그 지문을 저장할 사용하고 의미 사용하고 말 이렇게 출력 리디렉션 m :

MyProgram.exe inputfile > outputfile.txt 

난 메모리 및 하드 디스크의 차이를 알고 있지만, 왜 Console.WriteLine() (하드 디스크에 인쇄하는) 전술 한 바와 같이 출력 리디렉션을 사용하여, 인쇄 StreamWriter를 사용하는 것보다 1000 배 이상 빠릅니까?

아래와 같이 버퍼 크기를 늘리려고했지만 인쇄 속도가 빨라지지 않았습니다.

using (StreamWriter writer = new StreamWriter(@"C:\OuputFile.txt", true, Encoding.UTF8, 65536)) 

업데이트 2 : 모든

안녕하세요, 감사합니다 모든 도움, 당신은 rigth했다!. 모든 제안과 예제를 따라 StreamWriter를 외부에 정의했으며 PrintFunction과 이번에는 writer 프로세스가 한 번만 호출되고 출력 파일은 끝까지 열려 있고이 방법으로 인쇄 프로세스 속도는 Console.WrileLine()과 동일합니다. .

필자는 아래 함수와 같은 인수를 전달했으며 작동합니다. 나는 4KB, 64KB의 버퍼 크기로 테스트했고 아래에 표시된 것과 같이 디폴트 값을 사용했고, 더 빠른 결과는 명시 적으로 4096 바이트의 버퍼를 설정할 때였 다. 이 기능은 이라 불리우며 1000 만회 조금 넘었고 출력 파일은 670MB였습니다.

*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* 

다시 도움 주셔서 감사합니다.

감사

코드는 다음과 같습니다 : 내가 대신 Console.WriteLine의 StreamWriter는()를 사용할 때

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 
} 
+2

구입에게 SSD 디스크를, (솔리드 스테이트 디스크)하지만 여전히 메모리보다 느립니다. 메모리와 디스크의 차이점을 알고 있습니까? – Steve

+0

정확히 무엇을 의미합니까? "Console.WriteLine() 또는 Console.WriteLine()을 사용하면 출력 파일이 초당 3MB 또는 4MB 증가합니다."Console.WriteLine은 콘솔에 씁니다. 당신은 파일에 쓰기 위해 그것을 사용하고 있습니까? 표준 출력을 리디렉션 하시겠습니까? –

+3

콘솔에 쓰는 것이 File에 쓰는 것과 같지 않습니다. 나는 '질문을 이해하지 못한다. –

답변

2

저는 이것을 프로파일 링했으며 완전히 반대 인 것처럼 보입니다. SSD가없는 표준 10K rpm 드라이브에 약 .25GB/s를 기록 할 수있었습니다. 이 함수를 많이 호출하고 매번 새로운 함수에 연결하여 파일에 쓰는 것처럼 보입니다. (I 오래된 콘솔 로깅 코드 조각에서 신속하게 함께이 문제를 냈다, 그래서 약간의 버그가있을 수 있습니다, 및 오류 처리가 확실히 완료되지 않음) 같은 것을보십시오 :

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

왜 인쇄 속도가 너무 많이 감소? 당신이 파일에 명령 출력을 리디렉션 할 때

는 출력 파일의 쓰기 전용 액세스는 어떤 한 번 당신이 console.Write와 PrintFunction()를 호출 횟수()

에서 cmd.exe를 인수 한

PrintFunction()에서 스트림 기록기를 사용하는 경우 기록기가 매번 초기화되고 파일에 액세스하고 줄을 기록한 다음 파일 핸들을 해제하려고합니다. 오버 헤드로 인해 성능이 저하됩니다.

Console.WriteLine()과 같은 속도로 파일을 쓰려면 어떤 방법을 사용해야합니까?

당신은 (모두 StringBuilder를 사용하여 예) 다음 PrintFunction에 StreamWriter는 객체를 전달 한 번에

  • 파일에 쓸 다음

    1. 버퍼의 하나의 메모리에 모든 출력을 시도 할 수 있습니다() 오버 헤드를 피할 수 있습니다. StreamWriter.Close()를 적절하게 처리하십시오.
  • 관련 문제