2009-05-04 5 views
2

Mein PC hat eine Dual-Core-CPU und ich frage mich - wäre es möglich, .NET-Reflektionszeiten um zwei zu reduzieren, wenn ich in einem Zwei-Thread-Prozess beginne.Multi-Threading verwenden, um .NET-Reflektion zu beschleunigen

von "Verarbeitung" ich folgendes gemeint haben:

1.loading die Montage 2.getting alle Arten aus ihm heraus (.GetTypes()) 3.processing diese Art diese Arten 4.querying für Methoden usw.

Wenn ja - was ist die beste (Performance-weise) Strategie wäre:

  1. Last alle Baugruppen in einem ein Thread dann Prozess Metainformationen in einem zwei concurent Gewinde
  2. Last und Prozeß jede Anordnung in einem eigenen Thread

Antwort

1

Laden und Verarbeiten jede Baugruppe in einem separaten Thread ist schneller. Aber nur ein bisschen schneller. Zum Beispiel werden Sie durch das Caching von MethodInfos eine wesentlich bessere Kilometerleistung erhalten.

Ich würde jedoch die Notwendigkeit für eine solche Optimierung in Frage stellen.

Ergebnisse:

 
warm up single threaded Time Elapsed 465 ms 
multi threaded Time Elapsed 173 ms 
single threaded Time Elapsed 456 ms 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Reflection; 
using System.Diagnostics; 

namespace ConsoleApplication12 { 
    class Program { 


     static void TimeAction(string description, Action func) { 
      var watch = new Stopwatch(); 
      watch.Start(); 
      func(); 
      watch.Stop(); 
      Console.Write(description); 
      Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds); 
     } 

     static void Main(string[] args) { 

      var assemblies = AppDomain.CurrentDomain.GetAssemblies(); 

      // warm up 
      TimeAction("warm up single threaded",() => 
      { 
       foreach (var assembly in assemblies) { 
        assembly.GetTypes().Select(type => type.GetMethods()).ToArray(); 
       } 

      }); 

      List<Thread> threads = new List<Thread>(); 

      TimeAction("multi threaded",() => { 
       foreach (var assembly in assemblies) { 
        Thread t = new Thread(new ThreadStart(() => 
         assembly.GetTypes().Select(type => type.GetMethods()).ToArray() 
         )); 
        t.Start(); 
        threads.Add(t); 
       } 

       foreach (var thread in threads) { 
        thread.Join(); 
       } 
      }); 

      TimeAction("single threaded",() => 
      { 
       foreach (var assembly in assemblies) { 
        assembly.GetTypes().Select(type => type.GetMethods()).ToArray(); 
       } 

      }); 

      Console.ReadKey(); 
     } 
    } 
} 
1

Sofern Sie mit absolut umfangreichen Bibliotheken zu tun hat, ist die Reflexion Laden nicht schrecklich langsam, was in meinen Erfahrungen. Es ist möglich, dass es eine Verschwendung Ihrer Zeit wäre.

Dennoch überprüfen Sie ThreadPool.QueueUserWorkItem, macht das Zeug einfach.

foreach (Assembly a in "folder/something") { 
    ThreadPool.QueueUserWorkItem((object assem) => { 
     // do work 
    }, a); 
} 
3

Es gibt ein paar Dinge im Auge zu behalten:

  • ein neuer Thread ist teuer starten, so dass, wenn die Aufgabe kurz der Kopf gelebt wird unerschwinglich sein. Wenn Sie den Thread-Pool verwenden, anstatt eigene Threads zu starten, stellt der Thread-Pool sicher, Threads optimal zu nutzen. Das Starten einer großen Anzahl von Aufgaben in kurzer Zeit liefert jedoch mit der aktuellen Implementierung des Thread-Pools nicht das beste Ergebnis.

  • Da Ihre spezifische Aufgabe einige I/O beinhaltet, wird dies wahrscheinlich der teuerste Teil der Operation sein. Das Abzweigen mehrerer Threads zum Warten auf E/A führt möglicherweise nicht zu einer besseren Leistung. Sie können es nicht wirklich sagen, bis Sie es gemessen haben.

  • Wenn Sie die Daten in einem freigegebenen Repository speichern oder in einer Datei/auf dem Bildschirm ausgeben, müssen Sie dies synchronisieren. Dies reduziert offensichtlich die Nebenläufigkeit.

Verwandte Themen