2009-05-04 8 views
2

Mon PC a un processeur dual core et je me demandais - serait-il possible de réduire les temps de réflexion .NET par deux, si je commence le traitement dans un thread à deux threads.Utiliser le multi-thread pour accélérer la réflexion .NET

Par "traitement" J'ai signifié ce qui suit:

1.ESSAI DE CHARGE l'ensemble 2.getting tous les types hors de celui-ci (.GetTypes()) 3.processing ces types 4.querying ces types pour les méthodes etc.

Si oui - quelle serait la meilleure stratégie (performance-sage):

  1. charge tous les ensembles dans un processus, puis un fil metainfo dans deux concurent fils
  2. charge et traiter chaque ensemble dans son propre fil

Répondre

1

chargement et le traitement de chaque ensemble en un fil séparé est plus rapide. Mais seulement un peu plus vite. Par exemple, vous obtiendrez beaucoup mieux en mettant en cache MethodInfos.

Je doute cependant de la nécessité d'une telle optimisation.

résultats:

 
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

Sauf si vous faites affaire avec des bibliothèques absolument massives, le chargement de la réflexion est pas une chose terriblement lent, dans mes expériences. Il est possible que ce serait une perte de temps. Néanmoins, consultez ThreadPool.QueueUserWorkItem, rend ce truc facile.

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

Il y a deux choses à garder à l'esprit:

  • Démarrage d'un nouveau fil est cher, donc si la tâche est de courte durée la surcharge peut être prohibitif. En utilisant le pool de threads au lieu de démarrer vos propres threads, le pool de threads s'assurera de réutiliser les threads au mieux de ses capacités. Cependant, lancer beaucoup de tâches en peu de temps ne donne pas le meilleur résultat avec l'implémentation actuelle du pool de threads.

  • Étant donné que votre tâche spécifique implique certaines E/S qui vont probablement être la partie la plus coûteuse de l'opération. Le fait de débourrer plusieurs threads pour attendre les E/S peut ne pas donner de meilleures performances. Vous ne pouvez pas vraiment le dire avant de le mesurer.

  • Si vous stockez les données dans un référentiel partagé ou que vous les envoyez dans un fichier/à l'écran, vous devrez effectuer une synchronisation. Cela réduit évidemment la concurrence.

Questions connexes