2010-02-26 10 views
4

Quelqu'un peut-il m'aider à optimiser cette méthode?Optimisation de la méthode de remplacement de chaîne

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
{ 
    VirtualPathData path = base.GetVirtualPath(requestContext, values); 

    if (path != null) 
    { 
     string virtualPath = path.VirtualPath; 
     string condition = string.Empty; 

     if (virtualPath.Contains("?")) 
     { 
      condition = virtualPath.Substring(virtualPath.IndexOf("?")); 
      virtualPath = virtualPath.Substring(0, virtualPath.IndexOf("?")); 
     } 

     virtualPath = virtualPath.Replace(@"%C5%BD", "ž"); 
     virtualPath = virtualPath.Replace(@"%C4%90", "đ"); 
     virtualPath = virtualPath.Replace(@"%C4%86", "ć"); 
     virtualPath = virtualPath.Replace(@"%C4%8C", "č"); 
     virtualPath = virtualPath.Replace(@"%C5%A0", "š"); 

     virtualPath = virtualPath.ToLower().Replace(",", "-").Replace("%20", "-").Replace("&", "-"); 
     virtualPath = virtualPath.Replace(@"-amp;", "&"); 

     while (virtualPath.Contains("--")) 
     { 
      virtualPath = virtualPath.Replace("--", "-"); 
     } 

     path.VirtualPath = virtualPath + condition; 
    } 

    return path; 
} 

Répondre

4

Dans ce code, vous numérisez la chaîne à trois reprises pour un personnage:

if (virtualPath.Contains("?")) 
{ 
    condition = virtualPath.Substring(virtualPath.IndexOf("?")); 
    virtualPath = virtualPath.Substring(0, virtualPath.IndexOf("?")); 
} 

Au lieu de cela, le scanner une fois et utiliser trois fois le résultat. Rechercher également un caractère au lieu d'une chaîne:

int pos = virtualPath.IndexOf('?'); 
if (pos != -1) { 
    condition = virtualPath.Substring(pos); 
    virtualPath = virtualPath.Substring(0, pos); 
} 

Ici vous font plusieurs remplace avec le même remplacement:

virtualPath = virtualPath.ToLower().Replace(",", "-").Replace("%20", "-").Replace("&", "-"); 

Au lieu de cela vous pouvez utiliser une expression régulière pour correspondre à tous :

virtualPath = Regex.Replace(virtualPath.ToLower(), "(,|%20|&)", "-"); 

(Si cela donne effectivement de meilleures performances doit être testé avec certaines de vos données réelles. Eventhough il est moins opérations, il y a des frais généraux dans la mise en place du 'EXPRESSION régulière)


Vous utilisez une boucle pour réduire les groupes de caractères:.

while (virtualPath.Contains("--")) 
{ 
    virtualPath = virtualPath.Replace("--", "-"); 
} 

place, vous pouvez utiliser une expression régulière pour effectuez un remplacement unique:

virtualPath = Regex.Replace(virtualPath, "-{2,}", "-"); 
+0

Vous pouvez également fusionner l'expression '- {2,}' dans l'autre: '(, |% 20 | & | - {2,})' –

+0

@Joel, non je ne peux pas le fusionner, car si mon entrée est 'foo & foo', la sortie sera 'foo --- foo'. –

0

Votre première étape la plus évidente consisterait à utiliser StringBuilder au lieu d'une chaîne.

La chaîne est un type immuable. Cela signifie qu'une fois créée, sa valeur ne change jamais. Ainsi, pour chaque appel Remplacer que vous effectuez dans votre méthode, le programme créera une nouvelle instance de String pour stocker le résultat, qui nécessite beaucoup de mémoire et de processeur. (Je dis cela de façon comparative - vous n'allez pas utiliser cette méthode une seule fois, mais si vous l'appelez des milliers de fois, vous remarquerez certainement!)

StringBuilder, d'autre part, est une classe conçue pour manipuler des chaînes en mémoire et ne pas avoir à copier/recréer la mémoire chaque fois que vous changez la chaîne.

Ainsi, un grand pas dans la bonne direction serait d'utiliser ce au début de votre méthode:

  StringBuilder sb = new StringBuilder(path.VirtualPath.ToLower()); 
      string condition = string.Empty; 

      int index = path.VirtualPath.IndexOf("?"); 

      if (index > -1) 
      { 
       condition = virtualPath.Substring(pos); 
       sb.Remove(0, index); 
      } 

      sb.Replace(@"%C5%BD", "ž") 
       .Replace(@"%C4%90", "đ") 
       .Replace(@"%C4%86", "ć") 
       .Replace(@"%C4%8C", "č") 
       .Replace(@"%C5%A0", "š") 
       .Replace(",", "-") 
       .Replace("%20", "-") 
       .Replace("&", "-") 
       .Replace(@"-amp;", "&"); 
      sb.Append(condition); 

Notez que j'ai aussi fait le .ToLower() plus tôt parce que StringBuilder n'a pas équivalent, et notez également le sb.Append, ce qui empêchera encore beaucoup de réécriture.

Ce n'est pas aussi optimale que cela pourrait arriver, mais il devrait être tout à fait une amélioration ...

La seule chose que j'ai raté remplaçais le « - ». StringBuilder n'a pas de fonction "Contient", mais vous pouvez utiliser une expression régulière pour tout attraper en une passe (au lieu d'avoir besoin de la boucle).

J'espère que vous avez commencé!

Questions connexes