Analyse rapide de chaînes en C #

Quel est le moyen le plus rapide d’parsingr les chaînes en C #?

Actuellement, je n’utilise que l’indexation de chaîne ( ssortingng[index] ) et le code fonctionne de manière raisonnable, mais je ne peux pas m’empêcher de penser que la vérification continue de la plage que l’accesseur d’index doit append ajoute quelque chose.

Alors, je me demande quelles techniques je devrais envisager de donner un coup de pouce. Ce sont mes pensées / questions initiales:

  1. Utilisez des méthodes telles que ssortingng.IndexOf() et IndexOfAny() pour rechercher des caractères intéressants. Sont-ils plus rapides que l’parsing manuelle d’une chaîne par ssortingng[index] ?
  2. Utilisez les regex. Personnellement, je n’aime pas les regex car je les trouve difficiles à maintenir, mais sont-ils susceptibles d’être plus rapides que de balayer manuellement la chaîne?
  3. Utilisez du code et des pointeurs non sécurisés. Cela éliminerait la vérification de la plage d’index, mais j’ai lu que le code non sécurisé ne serait pas utilisé dans des environnements non fiables. Quelles sont exactement les implications de cela? Cela signifie-t-il que l’ensemble de l’assemblage ne sera pas chargé / exécuté ou que seul le code marqué non sécurisé refusera de s’exécuter? La bibliothèque pourrait potentiellement être utilisée dans un certain nombre d’environnements. Il serait bien de pouvoir revenir à un mode plus lent mais plus compatible.
  4. Que pourrais-je considérer?

NB: Je devrais dire que les chaînes que j’parsing peuvent être relativement grandes (par exemple, 30 Ko) et dans un format personnalisé pour lequel il n’existe pas d’parsingur .NET standard. En outre, la performance de ce code n’est pas très critique, c’est donc en partie une question théorique de curiosité.

30k n’est pas ce que je considérerais être grand. Avant de m’énerver, je profilerais. L’indexeur devrait convenir pour le meilleur équilibre entre flexibilité et sécurité.

Par exemple, pour créer une chaîne de 128 Ko (et un tableau séparé de la même taille), remplissez-la de junk (y compris le temps nécessaire pour gérer Random ) et additionnez tous les points de code de caractères via l’indexeur prend … 3ms:

  var watch = Stopwatch.StartNew(); char[] chars = new char[128 * 1024]; Random rand = new Random(); // fill with junk for (int i = 0; i < chars.Length; i++) chars[i] = (char) ((int) 'a' + rand.Next(26)); int sum = 0; string s = new string(chars); int len = s.Length; for(int i = 0 ; i < len ; i++) { sum += (int) chars[i]; } watch.Stop(); Console.WriteLine(sum); Console.WriteLine(watch.ElapsedMilliseconds + "ms"); Console.ReadLine(); 

Pour les fichiers de taille importante, une approche de lecteur doit être utilisée - StreamReader etc.

“Analyser” est un terme assez inexact. Puisque vous parlez de 30k, il semble que vous ayez peut-être affaire à une sorte de chaîne structurée qui peut être couverte en créant un parsingur utilisant un outil générateur d’parsingur.

Le système d’parsing GOLD de Devin Cook: http://www.devincook.com/goldparser/ est un bon outil pour créer, maintenir et comprendre l’ensemble du processus .

Cela peut vous aider à créer un code efficace et correct pour de nombreux besoins d’parsing syntaxique.

En ce qui concerne vos points:

  1. n’est généralement pas utile pour l’parsing qui va plus loin que le fractionnement d’une chaîne.

  2. convient mieux s’il n’ya pas de récursion ou de règles trop complexes.

  3. est fondamentalement un non-aller si vous ne l’avez pas vraiment identifié comme un problème grave. Le JIT peut s’occuper des vérifications de plage uniquement lorsque cela est nécessaire, et même pour les boucles simples (la boucle typique), cela est assez bien géré.