2010-12-29 5 views
1

J'écris un utilitaire en C# qui facilitera la gestion de plusieurs référentiels Mercurial pour la façon dont mon équipe l'utilise. Cependant, il semble qu'il y ait toujours un délai de 300 à 400 millisecondes avant que je reçois quelque chose de hg.exe. J'utilise le code ci-dessous pour exécuter hg.exe et hgtk.exe (GUI de TortoiseHg). Le code inclut actuellement un chronomètre et certaines variables à des fins de chronométrage. Le délai est à peu près le même sur plusieurs passages dans la même session. J'ai également essayé de spécifier le chemin exact de hg.exe, et j'ai obtenu le même résultat.Mercurial CLI est lent en C#?

static string RunCommand(string executable, string path, string arguments) 
{ 
    var psi = new ProcessStartInfo() 
    { 
     FileName = executable, 
     Arguments = arguments, 
     WorkingDirectory = path, 

     UseShellExecute = false, 
     RedirectStandardError = true, 
     RedirectStandardInput = true, 
     RedirectStandardOutput = true, 

     WindowStyle = ProcessWindowStyle.Maximized, 
     CreateNoWindow = true 
    }; 

    var sbOut = new StringBuilder(); 
    var sbErr = new StringBuilder(); 

    var sw = new Stopwatch(); 

    sw.Start(); 

    var process = Process.Start(psi); 

    TimeSpan firstRead = TimeSpan.Zero; 

    process.OutputDataReceived += (s, e) => 
    { 
     if (firstRead == TimeSpan.Zero) 
     { 
      firstRead = sw.Elapsed; 
     } 

     sbOut.Append(e.Data); 
    }; 
    process.ErrorDataReceived += (s, e) => sbErr.Append(e.Data); 

    process.BeginOutputReadLine(); 
    process.BeginErrorReadLine(); 

    var eventsStarted = sw.Elapsed; 

    process.WaitForExit(); 

    var processExited = sw.Elapsed; 

    sw.Reset(); 

    if (process.ExitCode != 0 || sbErr.Length > 0) 
    { 
     Error.Mercurial(process.ExitCode, sbOut.ToString(), sbErr.ToString()); 
    } 

    return sbOut.ToString(); 
} 

Des idées sur comment je peux accélérer les choses? Comme il est, je vais devoir faire beaucoup de mise en cache en plus de thread pour garder l'interface utilisateur accrocheur.

+0

Vous dites qu'il y a un délai avant que vous n'obteniez quoi que ce soit, ce délai est-il le même que le temps que le programme doit terminer? Ou une commande arbitraire prend 3-400 ms de plus pour exécuter votre programme que de la ligne de commande? Je ne peux pas dire que j'ai expérimenté que hg s'exécute plus lentement, mais il semble y avoir une mise en cache sur la sortie. En d'autres termes, il semble que mon programme n'obtiendra pas de nouvelles lignes de texte de hg car hg les recrache, seulement quand le tampon se remplit plus tard. –

+0

Aussi, je ne peux pas résister à l'envie de faire un peu d'auto-commercial :) J'ai fait une bibliothèque de classe pas encore terminée pour l'emballage Mercurial. Vous pouvez consulter mon code pour voir s'il y a des différences évidentes dans l'exécution du programme. Je vais faire quelques tests de timing maintenant, mais mes tests unitaires ne prennent pas tellement de temps, donc je ne pense pas avoir un tel retard. Il est trouvé ici: http://mercurialnet.codeplex.com/ –

+0

Je ne sais pas combien de temps il faut pour courir depuis la ligne de commande, je trouve juste que 300+ ms est inacceptable quand vous avez 26 (et en croissance) référentiels pour exécuter plusieurs commandes. Il suffit de 9 secondes pour trouver la branche sur laquelle il se trouve, et je dois aussi vérifier s'il y a des têtes à fusionner, entre autres choses. – Taudris

Répondre

2

Eh bien, voici l'affaire.

Le programme de ligne de commande mercurial contient un surcoût, c'est à peu près tout.

Cette commande:

hg --quiet version 

qui ne ressemble à aucun dépôt du tout, prend 195ms en moyenne sur ma machine à exécuter. Vous ne serez pas en mesure de minimiser cela beaucoup plus près de zéro lorsque vous commencez à impliquer des dépôts et des changesets.

Pourquoi avez-vous 26 dépôts? Pourquoi avez-vous besoin de savoir dans quelle branche ils se trouvent? Utilisez-vous des branches nommées et des répertoires multiples en même temps?

+0

Oui, j'utilise plusieurs repos et branches nommées. Le code est divisé en plusieurs bibliothèques qui sont utilisées dans différentes combinaisons entre différents projets. Je les ai donc conservées dans des référentiels distincts. Je ne veux pas d'une branche spécifique à un projet encombrant la liste des branches pour d'autres projets ... – Taudris

+0

Qu'en est-il des sous-dépôts, cela ne fonctionnerait-il pas? –