2016-04-05 13 views
1

Binlerce dosyayı olabildiğince hızlı açmam ve okuman gerek.Mümkün olduğu kadar hızlı binlerce dosyayı açın ve okuyun

13 592 dosya üzerinde birkaç test çalıştırdım ve Yöntem 1'den biraz daha hızlı olması için Yöntem 1'i buldum. Bu dosyalar genellikle 800 bayt ve 4kB arasındadır. Bu G/Ç işlemlerini daha hızlı yapmak için yapabileceğim bir şey olup olmadığını bilmek isterim.

public class FileOpenerUtil 
{ 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="fullFilePath"></param> 
    /// <returns></returns> 
    public static string ReadFileToString(string fullFilePath) 
    { 
     while (true) 
     { 
      try 
      { 
       //Methode 1 
       using (StreamReader sr = File.OpenText(fullFilePath)) 
       { 
        string fullMessage = ""; 
        string s; 
        while ((s = sr.ReadLine()) != null) 
        { 
         fullMessage += s + "\n"; 
        } 
        return RemoveCarriageReturn(fullMessage); 
       } 
       //Methode 2 
       /*using (File.Open(fullFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
       { 
        Console.WriteLine("Output file {0} ready.", fullFilePath); 
        string[] lines = File.ReadAllLines(fullFilePath); 
        //Every new line under the previous line 
        string fullMessage = lines.Aggregate("", (current, s) => current + s + "\n"); 
        return RemoveCarriageReturn(fullMessage); 
        //ninject kernel 


       }*/ 
       //Methode 3 

      } 
      catch (FileNotFoundException ex) 
      { 
       Console.WriteLine("Output file {0} not yet ready ({1})", fullFilePath, ex.Message); 
      } 
      catch (IOException ex) 
      { 
       Console.WriteLine("Output file {0} not yet ready ({1})", fullFilePath, ex.Message); 
      } 
      catch (UnauthorizedAccessException ex) 
      { 
       Console.WriteLine("Output file {0} not yet ready ({1})", fullFilePath, ex.Message); 
      } 
     } 

    } 

    /// <summary> 
    /// Verwijdert '\r' in een string sequence 
    /// </summary> 
    /// <param name="message">The text that has to be changed</param> 
    /// <returns>The changed text</returns> 
    private static string RemoveCarriageReturn(string message) 
    { 
     return message.Replace("\r", ""); 
    } 
} 

okuyorum dosyalar .HL7 dosyalardır ve şu şekilde görünür:: İşte

Method 1: 
    Run 1: 3:05 (don't know what happened here) 
    Run 2: 1:55 
    Run 3: 2:06 
    Run 4: 2:02 
Method 2: 
    Run 1: 2:04 
    Run 2: 2:08 
    Run 3: 2:04 
    Run 4: 2:12 

kod

MSH |^~ \ & | OAZIS ||| | 20150430235954 || ADT^A03 | 23669166 | P | 2.3 |||||| ASCII EVN | A03 | 20150430235954 |||| 201504302359 PID | 1 || 6001144000 || LastName^FirstName^^^Mevr. | LastName^FirstName | 19600114 | F ||| GStreetName Numarası ^^ Şehir ^^ PostalCo de^B^H || 09/3444556 ^^ PH ~ 0476519246echtg^CP || NL | M || 28783409 ^^^^ VN | 0000000000 | 60011402843 |||||| B |||| N PD1 | ||| 003847^LastName^FirstName |||||||| N ||| 0 PV1 | 1 | O | FDAG^000^053^001^0^2 | NULL || FDAG^000^053^001 | 003847^Soyadı^ad || 006813^Soyadı^ad | 1900 | |||||| 006813 00^Soyadı^ad | 0 | 28783409 ^^^^ VN |^20150430 1 | 01 ||||||| |||||||| 1 | 1 || D ||||| 201504301336 | 201504302359 OBX | 1 | CE | KIND_OF_DIS | RCM | 1^1 Op medisch advies OBX | 2 | CE | DESTINATION_DIS | RCM | 1^1 Terug naar huis

Dosyayı açtığımda, dizeyi j4jayant's HL7 parser ile ayrıştırıyorum ve dosyayı kapatın.

+1

"Burada ne olduğu" ile ilgili olarak, genellikle ilk çalışma her zaman daha sonraki çalışmalardan daha yavaştır (jitter yüzünden?). Yöntem 1 ve 2'yi değiştirmeyi deneyin ve muhtemelen şimdi yöntem 2'nin ilk çalıştırmasının daha yavaş olacağını göreceksiniz. – Corak

+0

Yöntem 2'de “Console.WriteLine” öğesine çağrıyı kaldırarak (veya söyleyerek) başlatarak başlatın. Konsola yazma, performans üzerinde önemli bir etkiye sahiptir. –

+0

'fullMessage + = s +" \ n ";' 'StringBuilder' biraz daha hızlı olmalıdır. – BWA

cevap

2

I değişen boyutta (500-1024 bayt) 50.000 kullanılan dosyaları.

Testi 1: Yöntemin 1 StreamReader sr = File.OpenText(fullFilePath); sr.ReadLine();
saniye: 2 3,4658937968113
Testi: Yöntemin 2 File.ReadAllLines(fullFilePath)
saniye: 5,5008349279222
Testi 3: File.ReadAllText(fullFilePath);
saniye: 3,30782645637133
Test 4: BinaryReader b = new BinaryReader; b.ReadString();
saniye: 5,85779941381009
Test 5: Windows FileReader (https://msdn.microsoft.com/en-us/library/2d9wy99d.aspx)
saniye: 3,07036554759848
Test 6: StreamReader sr = File.OpenText(fullFilePath); sr.ReadToEnd();
saniye: 3,31464109255517
Test 7: StreamReader sr = File.OpenText(fullFilePath); sr.ReadToEnd();
Saniye: 3,3364683664508
Test 8: StreamReader sr = File.OpenText(fullFilePath); sr.ReadLine();
saniye: 3,40426888695317
Deney 9: FileStream + BufferedStream + StreamReader
saniye: 4,02871911079061
Deney 10: Parallel.For using code File.ReadAllText(fullFilePath);
saniye: 0,89543632235447

iyi testi sonuçlar Test 5 ve Test 3 (tek iplik)
Testi 3 kullanıyor: 5
Windows FileReader (https://msdn.microsoft.com/en-us/library/2d9wy99d.aspx) kullanır File.ReadAllText(fullFilePath);
Testi

kullanabilirsiniz ise ipler 10 arayla en hızlı olduğu test edin.

örnek:

int maxFiles = 50000; 
int j = 0; 
Parallel.For(0, maxFiles, x => 
{ 
    Util.Method1("readtext_" + j + ".txt"); // your read method 
    j++; 
}); 


bekleme listesine boşaltmak için RAMMap kullanarak:

Testi 1: Yöntemin 1 StreamReader sr = File.OpenText(fullFilePath); sr.ReadLine();
saniye: 15,1785750622961
Testi 2 : Yöntem 2 File.ReadAllLines(fullFilePath)
saniye: 17,650864469466
Test 3: File.ReadAllText(fullFilePath);
saniye: 14,8985912878328
Test 4: BinaryReader b = new BinaryReader; b.ReadString();
saniye: 18,1603815767866
Test 5: Windows FileReader
saniye: 14, 5059765845334
Test 6: StreamReader sr = File.OpenText(fullFilePath); sr.ReadToEnd();
Saniye: 14,864978 6336991
Test 7: StreamReader sr = File.OpenText(fullFilePath); sr.ReadToEnd();
saniye: 14,830567197641
Test 8: StreamReader sr = File.OpenText(fullFilePath); sr.ReadLine();
saniye: 14,9965866575751
Deney 9: FileStream + BufferedStream + StreamReader
saniye: 15,7336450516575
Test 10: Parallel.For() using code File.ReadAllText(fullFilePath);
Saniye: 4,11343060325 439

+1

Dikkat edilmesi gereken bir şey var: Eğer başka bir değişiklik yoksa ve birden fazla iş parçacığı kullanmak verinin okunmasını hızlandırıyorsa, veri okuma IO'da darboğazlanmamıştı. Ayrıca, tüm önbellekleri temizledikten sonra ** Test 10 ** 'ü tekrar denemeyi deneyebilirim: http://stackoverflow.com/questions/478340/clear-file-cache-to-repeat-performance-testing –

1

Tüm kodları yorumlardan uyguladım. Yöntem 1 hala en hızlı gibi görünüyor.

public class FileOpenerUtil 
{ 

/// <summary> 
/// 
/// </summary> 
/// <param name="fullFilePath"></param> 
/// <returns></returns> 
public static string ReadFileToString(string fullFilePath) 
{ 
    while (true) 
    { 
     try 
     { 
      //Method 1 
      using (StreamReader sr = File.OpenText(fullFilePath)) 
       { 
        string s; 
        StringBuilder message = new StringBuilder(); 
        while ((s = sr.ReadLine()) != null) 
        { 
         message.Append(s).Append("\n"); 
        } 
        return RemoveCarriageReturn(message.ToString()); 
       } 
      //Method 2 
      /* 
       string[] lines = File.ReadAllLines(fullFilePath); 
       string fullMessage = lines.Aggregate("", (current, s) =>          current + s + "\n"); 
       return RemoveCarriageReturn(fullMessage);*/ 

      } 
      //Method 3 
      /* 
       string s = File.ReadAllText(fullFilePath); 
       return RemoveCarriageReturn(s);*/ 
     } 
     catch (FileNotFoundException ex) 
     { 
      Console.WriteLine("Output file {0} not yet ready ({1})", fullFilePath, ex.Message); 
     } 
     catch (IOException ex) 
     { 
      Console.WriteLine("Output file {0} not yet ready ({1})", fullFilePath, ex.Message); 
     } 
     catch (UnauthorizedAccessException ex) 
     { 
      Console.WriteLine("Output file {0} not yet ready ({1})", fullFilePath, ex.Message); 
     } 
    } 

} 

/// <summary> 
/// Verwijdert '\r' in een string sequence 
/// </summary> 
/// <param name="message">The text that has to be changed</param> 
/// <returns>The changed text</returns> 
private static string RemoveCarriageReturn(string message) 
{ 
    return message.Replace("\r", ""); 
} 

}