IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Framework .NET Discussion :

Performance des Regex en .NET


Sujet :

Framework .NET

  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mai 2003
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Suisse

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2003
    Messages : 323
    Par défaut Performance des Regex en .NET
    Bonjour,

    A la recherche d'une méthode pour supprimer les accents d'une chaine de caractère afin de faciliter la comparaison entre 2 chaînes, j'ai implémenter plusieurs solutions et me suis intéressé aux performances.

    Comme j'ai relevé des différences notables entre ces solutions et entre les versions du Framework, je me suis dit que cela pourrait interesser d'autres développeurs

    Voici le code que j'utilise en boucle (> 40000 itérations) et plusieurs fois dans une autre methode pour comparer les resultats.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
           public static string RemoveDiacritics(string inputString)
            {
                string result = inputString.Trim().ToLower();
                // nothing: algo takes 2,06 s
                //string res0 = result;
                // Method1: String.Replace   -> 2,28s 
                //string res1 = RemoveDiacriticsStringReplace(result);
                // Method2: char replace + string builder -> 2,25s
                //string res2 = RemoveDiacriticsCharReplace(result);
                // Method3: Regex.Replace -> 5,8 s -> 2 times slower
                //string res3 = RemoveDiacriticsRegex(result);
                // Method4, need .NET 2.0: normalization -> 2,28 s
                string res4 = RemoveDiacriticsNormalizationDotNet2(result);
                //Debug.Assert(res1 == res2 && res1 == res3 && res1 == res4 && res2 == res3 && res2 == res4 && res3 == res4);
                return res4;
            }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
            public static string RemoveDiacriticsStringReplace(string inputString)
            {
                string result = inputString;
                result = result.Replace('à', 'a');
                result = result.Replace('á', 'a');
                result = result.Replace('ä', 'a');
                result = result.Replace('â', 'a');
                result = result.Replace('ã', 'a');
                result = result.Replace('å', 'a');
                result = result.Replace('é', 'e');
                result = result.Replace('è', 'e');
                result = result.Replace('ê', 'e');
                result = result.Replace('ë', 'e');
                result = result.Replace('ì', 'i');
                result = result.Replace('í', 'i');
                result = result.Replace('ï', 'i');
                result = result.Replace('î', 'i');
                result = result.Replace('ò', 'o');
                result = result.Replace('ó', 'o');
                result = result.Replace('ô', 'o');
                result = result.Replace('ö', 'o');
                result = result.Replace('û', 'u');
                result = result.Replace('ü', 'u');
                result = result.Replace('ù', 'u');
                result = result.Replace('ú', 'u');
                result = result.Replace('ý', 'y');
                result = result.Replace('ÿ', 'y');
                result = result.Replace('ç', 'c');
                result = result.Replace('ñ', 'n');            
                return result;
            }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
            public static string RemoveDiacriticsCharReplace(string inputString)
            {
                string result;
                StringBuilder builder = new StringBuilder();
                char[] car = inputString.ToCharArray();
                foreach (char c in car)
                {
                    if (c == 'ä' || c == 'á' || c == 'à' || c == 'â' || c == 'ã' || c == 'å')
                        builder.Append('a');
                    else if (c == 'é' || c == 'è' || c == 'ê' || c == 'ë')
                        builder.Append('e');
                    else if (c == 'ì' || c == 'í' || c == 'ï' || c == 'î')
                        builder.Append('i');
                    else if (c == 'ò' || c == 'ó' || c == 'ô' || c == 'ö')
                        builder.Append('o');
                    else if (c == 'ù' || c == 'ú' || c == 'ü' || c == 'û')
                        builder.Append('u');
                    else if (c == 'ÿ' || c == 'ý')
                        builder.Append('y');
                    else if (c == 'ç')
                        builder.Append('c');
                    else if (c == 'ñ')
                        builder.Append('n');
                    else builder.Append(c);
                }
                result = builder.ToString();
                return result;
            }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
            public static string RemoveDiacriticsRegex(string inputString)
            {
                string result = inputString;
                result = System.Text.RegularExpressions.Regex.Replace(result, @"(à|á|ä|â|ã|å)+", "a");
                result = System.Text.RegularExpressions.Regex.Replace(result, @"(é|è|ê|ë)+", "e");
                result = System.Text.RegularExpressions.Regex.Replace(result, @"(ì|í|ï|î)+", "i");
                result = System.Text.RegularExpressions.Regex.Replace(result, @"(ò|ó|ö|ô)+", "o");
                result = System.Text.RegularExpressions.Regex.Replace(result, @"(ü|û|ù|ú)+", "u");
                result = System.Text.RegularExpressions.Regex.Replace(result, @"(ÿ|ý)+", "y");
                result = System.Text.RegularExpressions.Regex.Replace(result, @"(ç)+", "c");
                result = System.Text.RegularExpressions.Regex.Replace(result, @"(ñ)+", "n");
                return result;
            }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
            public static string RemoveDiacriticsNormalizationDotNet2(string inputString)
            {
                string result = inputString;
                String normalizedString = result.Normalize(NormalizationForm.FormD);
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < normalizedString.Length; i++)
                {
                    Char c = normalizedString[i];
                    if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                        stringBuilder.Append(c);
                }
                result = stringBuilder.ToString();
                return result;
            }
    Et voici les résultats en temps d'exécution (secondes): j'ai juste changé les commentaires dans ma méthode principale RemoveDiacritics.
    Et j'ai compilé mon code sous VS2003 aussi bien que sous VS2005.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                    .net2     .net1.1
    rien            2,06      1,85
    string replace  2,28      2,41      
    char replace    2,25      2,15
    regex           5,8      22 !!
    normalization   2,28      n/a
    J'ai lancé chq test 4-5 fois et fait la moyenne ici.

    Deux points particulièrement intéressant concernant les Regex:
    1) c'est plus lent que des simples Replace
    2) cela a été drolement bien amélioré dans le .NET 2.0 !
    -> les regex sont 2 fois plus lentes que des replaces en .NET 2.0 mais 10 fois plus lentes en 1.1!

    Petite remarque sur mes regex: elles ne sont pas tout à fait correctes puisqu'elles remplacent par ex un "éé" en "e" au lieu de "ee".

    Enfin, la seule méthode qui soit complète est celle utilisant les classes Normalization et CharUnicodeInfo. Les autres sont du manuels où j'ai mis seulement les élements nécessaires (via mon Assert).

    Que dites vous de tels résultats? Impressionnants qd meme, non?

  2. #2
    Rédacteur

    Avatar de Jérôme Lambert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2003
    Messages
    4 451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 451
    Par défaut
    Pour Regex, je m'y attendais à ce que ce soit 2 fois plus lent qu'un simple String. Mais la différence avec la version 1 du Framework me surprend et me choque énormément

    En tout cas, très bonne idée d'avoir pris la peine de faire de tels tests sur ce point.

  3. #3
    Membre Expert Avatar de Mose
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 143
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 143
    Par défaut
    Très bonne idée ce test.
    Mais la chaîne d'entrée est-elle aléatoire ?

    Note : Pas très étonné pour les Regex, quand on sait comment c'est implémenté derrière.
    Pour info, si tu utilises plusieurs fois la même Regex, tu peux spécifier l'option Compiled pour aller plus vite (ça évite de refaire à chaque fois l'étape de parsing de ta regex)

  4. #4
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mai 2003
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Suisse

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2003
    Messages : 323
    Par défaut
    en fait, cette méthode fait partie d'un algorithme de filtrage (recherche de doublons) à partir d'une liste multi colonne de environ 44000 lignes, donc je parcourre plusieurs fois la listes et compare les string des colonnes sélectionnées.

    j'avais commencé par un programme .NET 1.1 qui recherchait pour chq ligne les redondances dans toutes les autres lignes, mais cela prennait trop de temps (dans les 5-6 min), et ai donc optimisé drastiquement en triant au préalable ma liste afin de chercher que dans les lignes suivantes tant que les valeurs sont égales. C'est là que j'obtiens ds les 2 sec de temps d'exécution.

    Ensuite, j'ai implémenté cette méthode de suppression des accents pour rechercher plus de doublons. A vrai dire, j'ai d'abord trouvé sur des blogs la méthode dotnet 2.0, et ai donc exporté ma solution vers vs2005, mais comme j'avais des petits soucis ds certains cas avec ma gestion multithreads, je suis repassé au 1.1.
    J'ai alors commencé par utiliser les regex pour avoir du code concis, mais vu le temps d'exécution, je me suis intéressé aux simples replace. Et c'est seulement ds un deuxieme temps que j'ai eu la curiosité de tester les memes algo ds ma solution .NET 2.0, et c'est en effet la différence entre les 2 Framework qui m'a le + impressionné et motivé pour poster ici.

    Au final, je suis resté avec la methode de normalisation en .NET 2.0 et avec le char.Replace en 1.1: les regex ici ne font que ralentir le tout.

    Tout cela pour dire que la chaîne d'entrée n'est donc pas du tout aléatoire puisque issue d'une liste triée.

    C'est quoi l'option Compiled dont du parles?

  5. #5
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Désolé pour ce petit hors sujet, mais j'utilise la méthode suivante pour supprimer les accents.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    string str = "àâäéèêëîïôöùûü";
    byte[] tab = System.Text.Encoding.GetEncoding(1251).GetBytes(str);
    string result = System.Text.Encoding.ASCII.GetString(tab);
    Elle me donne entière satisfaction (pour des langues autres que le français je ne sais pas, mais en français aucun problème) et j'aurai bien voulu savoir s'il était possible d'avoir les performances de cette méthode dans le même cadre que les tests précédents

  6. #6
    Membre Expert Avatar de Mose
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 143
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 143
    Par défaut
    Citation Envoyé par Eric80
    C'est quoi l'option Compiled dont du parles?
    RegexOptions.Compiled
    Un paramètre de l'objet Regex.

  7. #7
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Par défaut
    en utilisant une chaine bateau de 60 caractères, avec le code suivant, ca met
    190 millisecondes... record à battre ?

    The Monz, Toulouse

    Le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
            private void button1_Click(object sender, EventArgs e)
            {
                Stopwatch clock = new Stopwatch();
                string str = "à la claîre fontaîne l'élève à fait de grâve erreur où pas ?";
                clock.Start();
                for (int i = 0; i < 40000; i++)
                {
                    Method(str);
                }
     
                clock.Stop();
                MessageBox.Show(clock.ElapsedMilliseconds.ToString());
     
            }
     
            private string Method(String str)
            {
                byte[] tab = System.Text.Encoding.GetEncoding(1251).GetBytes(str);
                return (System.Text.Encoding.ASCII.GetString(tab));
            }
    Test sur PIV 2.4 Ghz 1Go de Ram, windows XP SP2. Framework 2.0

    (c'était pour pouvoir comparer car à proc équivalent... ca serait mieux)

    EDIT : en mettant la methode en static plutot que juste private, on gagne
    sur ma machine 6 ms (c'est peu mais bon, c'est utile de la savoir

  8. #8
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Par défaut
    Salut .

    Par curiosité on peut avoir le code source du test ?

    Je voudrais le faire tourner sous Mono mais j'ai la fleme d'écrire le code (re )

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2006
    Messages : 51
    Par défaut
    Bonjour à tous.

    Je relance le poste 3 ans plus tard pour une question.

    Si on prend l'algorithme de Eric le plus rapide, soit le charReplace.

    On est bien d'accord qu'à chaque caractère non accentué, on effectue 8 tests, pour ensuite ajouter le caractère.

    On est aussi d'accord qu'il y a beaucoup, beaucoup moins de lettres accentuées que de non accentuées.

    Et si on faisait ca alors :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    foreach (char c in car)
                {
                    if (Regex.IsMatch(c.ToString(), "[A-Za-z]"))
                        builder.Append(c);
                    else if (c == 'ä' || c == 'á' || c == 'à' || c == 'â' || c == 'ã' || c == 'å')
                        builder.Append('a');
                    else if (c == 'é' || c == 'è' || c == 'ê' || c == 'ë')
                        builder.Append('e');
                    else if (c == 'ì' || c == 'í' || c == 'ï' || c == 'î')
                        builder.Append('i');
                    else if (c == 'ò' || c == 'ó' || c == 'ô' || c == 'ö')
                        builder.Append('o');
                    else if (c == 'ù' || c == 'ú' || c == 'ü' || c == 'û')
                        builder.Append('u');
                    else if (c == 'ÿ' || c == 'ý')
                        builder.Append('y');
                    else if (c == 'ç')
                        builder.Append('c');
                    else if (c == 'ñ')
                        builder.Append('n');
                    else
                        builder.Append(c);
                }
    On ajoute un test à chaque caractère accentué, mais on supprime 8 test à chaque caractère non accentué. Je sais que se ne sont pas les tests qui prennent le plus de temps, mais dans le cas (le miens en l'occurrence) ou je vais tester 19'000 chaînes, chacune de 20 à 30 caractères, cela fais tout de même pas mal de tests d'économisés.

    Petite remarque, j'ai également laissé le else à la fin, au cas où un caractère accentué ait été oublié, qu'on l'ajoute quand même (a voir au cas par cas, se qui est le mieux).

    Après, je ne sais pas si l'utilisation du Regex prend plus de temps.

    J'effectuerai les test et je posterai mes conclusions ici bientôt, mais est-ce que quelqu'un a déjà n élément de réponse ?

    Merci

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2006
    Messages : 51
    Par défaut
    Hé bien après plusieurs tests, j'ai eu le même constat que Eric :

    Pour une liste de 20'000 éléments de type string, contenant chacune
    Les résultats sont les suivants (valeurs en nombre de ticks) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    StringReplace : 82862
    CharReplace : 41907
    Regex : 725189
    DotNet2 : 83554
    Version modifiée que j'ai proposée : 703825
    Le résultat est très claire, le charReplace est bien meilleurs. Les résultats sont plus ou moins identiques avec des strings plus longues et/ou sans accents.

    On peut donc tirer la conclusion d'un Regex est beaucoup plus lourd que 8 test.

    Voilà, j'espère que je dépannerai quelqu'un... En tout cas, ca m'a bien été personnellement !

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 99
    Par défaut
    J'ai refait les tests avec le 3.5 et j'obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     Method                               | Time             | Perf
    --------------------------------------+------------------+------
     RemoveDiacriticsCharReplace          | 00:00:00.3281229 | 1,00
     RemoveDiacriticsTrick                | 00:00:00.5468715 | 1,67
     RemoveDiacriticsStringReplace        | 00:00:00.6093711 | 1,86
     RemoveDiacriticsNormalizationDotNet2 | 00:00:00.7812450 | 2,38
     RemoveDiacriticsRegex                | 00:00:01.2031173 | 3,67
    avec le code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
     
    namespace ConsoleApplication1
    {
        using System;
        using System.Collections.Generic;
        using System.Globalization;
        using System.Linq;
        using System.Text;
        using System.Text.RegularExpressions;
     
        public class Program
        {
            #region Fields
     
            private const char CrossSymbol = '+';
            private const char HorizontalSeparatorSymbol = '-';
            private const int IterationCount = 200000;
            private const string MethodHeader = "Method";
            private const string PerformanceFormat = "#,##0.00";
            private const string PerformanceHeader = "Perf";
            private const string RemoveDiacriticsCharReplaceMethodName = "RemoveDiacriticsCharReplace";
            private const string RemoveDiacriticsNormalizationDotNet2MethodName = "RemoveDiacriticsNormalizationDotNet2";
            private const string RemoveDiacriticsRegexMethodName = "RemoveDiacriticsRegex";
            private const string RemoveDiacriticsStringReplaceMethodName = "RemoveDiacriticsStringReplace";
            private const string RemoveDiacriticsTrickMethodName = "RemoveDiacriticsTrick";
            private const char SpaceSymbol = ' ';
            private const string TestString = "à la claîre fontaîne l'élève à fait de grâve erreur où pas ?";
            private const string TimeHeader = "Time";
            private const char VerticalSeparatorSymbol = '|';
     
            #endregion Fields
     
            #region Properties
     
            private static Dictionary<string, string> Chars
            {
                get;
                set;
            }
     
            private static Regex Regex
            {
                get;
                set;
            }
     
            #endregion Properties
     
            #region Methods
     
            public static void Main(string[] args)
            {
                Init();
                var oMethodsToTest = new List<Pair<Func<string, string>, string>>();
                oMethodsToTest.Add(new Pair<Func<string, string>, string>(RemoveDiacriticsRegex, RemoveDiacriticsRegexMethodName));
                oMethodsToTest.Add(new Pair<Func<string, string>, string>(RemoveDiacriticsNormalizationDotNet2, RemoveDiacriticsNormalizationDotNet2MethodName));
                oMethodsToTest.Add(new Pair<Func<string, string>, string>(RemoveDiacriticsStringReplace, RemoveDiacriticsStringReplaceMethodName));
                oMethodsToTest.Add(new Pair<Func<string, string>, string>(RemoveDiacriticsCharReplace, RemoveDiacriticsCharReplaceMethodName));
                oMethodsToTest.Add(new Pair<Func<string, string>, string>(RemoveDiacriticsTrick, RemoveDiacriticsTrickMethodName));
                var oResults = oMethodsToTest
                .Select(x => new Pair<TimeSpan, string>(TestMethod(x.Fst), x.Snd))
                .OrderBy(x => x.Fst)
                .ToArray();
                var oBest = oResults.First().Fst;
                var sTable = new string[oResults.Length + 1][];
                for (var i = 0; i < sTable.Length; i++)
                {
                    sTable[i] = new string[3];
                }
                sTable[0][0] = MethodHeader;
                sTable[0][1] = TimeHeader;
                sTable[0][2] = PerformanceHeader;
                for (var i = 0; i < oResults.Length; i++)
                {
                    sTable[i + 1][0] = oResults[i].Snd;
                    sTable[i + 1][1] = oResults[i].Fst.ToString();
                    var fGap = (double)oResults[i].Fst.Ticks / (double)oBest.Ticks;
                    sTable[i + 1][2] = fGap.ToString(PerformanceFormat);
                }
                WriteTable(sTable);
                System.Console.ReadLine();
            }
     
            private static void Init()
            {
                Chars = new Dictionary<string, string>();
                Chars["c"] = "c";
                Chars["à"] = "a";
                Chars["á"] = "a";
                Chars["ä"] = "a";
                Chars["â"] = "a";
                Chars["ã"] = "a";
                Chars["å"] = "a";
                Chars["é"] = "e";
                Chars["è"] = "e";
                Chars["ê"] = "e";
                Chars["ë"] = "e";
                Chars["ì"] = "i";
                Chars["í"] = "i";
                Chars["ï"] = "i";
                Chars["î"] = "i";
                Chars["ò"] = "o";
                Chars["ó"] = "o";
                Chars["ô"] = "o";
                Chars["ö"] = "o";
                Chars["û"] = "u";
                Chars["ü"] = "u";
                Chars["ù"] = "u";
                Chars["ú"] = "u";
                Chars["ý"] = "y";
                Chars["ÿ"] = "y";
                Chars["ç"] = "c";
                Chars["ñ"] = "n";
                var sPattern = string.Join(VerticalSeparatorSymbol.ToString(), Chars.Keys.Select(x => x.ToString()).ToArray());
                Regex = new System.Text.RegularExpressions.Regex(sPattern, RegexOptions.Compiled);
            }
     
            private static string RemoveDiacriticsCharReplace(string inputString)
            {
                string result;
                StringBuilder builder = new StringBuilder();
                char[] car = inputString.ToCharArray();
                foreach (char c in car)
                {
                    if (c == 'ä' || c == 'á' || c == 'à' || c == 'â' || c == 'ã' || c == 'å')
                        builder.Append('a');
                    else if (c == 'é' || c == 'è' || c == 'ê' || c == 'ë')
                        builder.Append('e');
                    else if (c == 'ì' || c == 'í' || c == 'ï' || c == 'î')
                        builder.Append('i');
                    else if (c == 'ò' || c == 'ó' || c == 'ô' || c == 'ö')
                        builder.Append('o');
                    else if (c == 'ù' || c == 'ú' || c == 'ü' || c == 'û')
                        builder.Append('u');
                    else if (c == 'ÿ' || c == 'ý')
                        builder.Append('y');
                    else if (c == 'ç')
                        builder.Append('c');
                    else if (c == 'ñ')
                        builder.Append('n');
                    else builder.Append(c);
                }
                result = builder.ToString();
                return result;
            }
     
            private static string RemoveDiacriticsNormalizationDotNet2(string inputString)
            {
                string result = inputString;
                string normalizedString = result.Normalize(NormalizationForm.FormD);
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < normalizedString.Length; i++)
                {
                    char c = normalizedString[i];
                    if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                        stringBuilder.Append(c);
                }
                result = stringBuilder.ToString();
                return result;
            }
     
            private static string RemoveDiacriticsRegex(string inputString)
            {
                return Regex.Replace(inputString, ReplaceMatch);
            }
     
            private static string RemoveDiacriticsStringReplace(string inputString)
            {
                string result = inputString;
                result = result.Replace('à', 'a');
                result = result.Replace('á', 'a');
                result = result.Replace('ä', 'a');
                result = result.Replace('â', 'a');
                result = result.Replace('ã', 'a');
                result = result.Replace('å', 'a');
                result = result.Replace('é', 'e');
                result = result.Replace('è', 'e');
                result = result.Replace('ê', 'e');
                result = result.Replace('ë', 'e');
                result = result.Replace('ì', 'i');
                result = result.Replace('í', 'i');
                result = result.Replace('ï', 'i');
                result = result.Replace('î', 'i');
                result = result.Replace('ò', 'o');
                result = result.Replace('ó', 'o');
                result = result.Replace('ô', 'o');
                result = result.Replace('ö', 'o');
                result = result.Replace('û', 'u');
                result = result.Replace('ü', 'u');
                result = result.Replace('ù', 'u');
                result = result.Replace('ú', 'u');
                result = result.Replace('ý', 'y');
                result = result.Replace('ÿ', 'y');
                result = result.Replace('ç', 'c');
                result = result.Replace('ñ', 'n');
                return result;
            }
     
            private static string RemoveDiacriticsTrick(string inputString)
            {
                byte[] tab = System.Text.Encoding.GetEncoding(1251).GetBytes(inputString);
                string result = System.Text.Encoding.ASCII.GetString(tab);
                return result;
            }
     
            private static string ReplaceMatch(Match match)
            {
                return Chars[match.Value];
            }
     
            private static TimeSpan TestMethod(Func<string, string> method)
            {
                var oStart = DateTime.Now;
                var sStr = TestString;
                for (var i = 0; i < IterationCount; i++)
                {
                    method(sStr);
                }
                var oStop = DateTime.Now;
                return oStop - oStart;
            }
     
            private static void WriteTable(string[][] values)
            {
                var iRows = values.Length;
                var iCols = values[0].Length;
                var iColumnsWidth = new int[iCols];
                for (var j = 0; j < iCols; j++)
                {
                    iColumnsWidth[j] = 0;
                }
                for (var j = 0; j < iCols; j++)
                {
                    for (var i = 0; i < iRows; i++)
                    {
                        iColumnsWidth[j] = Math.Max(iColumnsWidth[j], values[i][j].Length);
                    }
                }
                for (var i = 0; i < iRows; i++)
                {
                    if (i == 1)
                    {
                        for (var j = 0; j < iCols; j++)
                        {
                            if (j >= 1)
                            {
                                System.Console.Write(CrossSymbol);
                            }
                            System.Console.Write(new string(HorizontalSeparatorSymbol, iColumnsWidth[j] + 2));
                        }
                        System.Console.WriteLine();
                    }
                    for (var j = 0; j < iCols; j++)
                    {
                        if (j >= 1)
                        {
                            System.Console.Write(VerticalSeparatorSymbol);
                        }
                        System.Console.Write(SpaceSymbol);
                        System.Console.Write(values[i][j]);
                        System.Console.Write(new string(' ', iColumnsWidth[j] - values[i][j].Length + 1));
                    }
                    System.Console.WriteLine();
                }
            }
     
            #endregion Methods
        }
    }
    les regex sont tjs qqch de lent

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Performance des Datasets
    Par Nafanga dans le forum Bases de données
    Réponses: 6
    Dernier message: 10/10/2005, 00h49
  2. performances des virtual functions
    Par xxiemeciel dans le forum C++
    Réponses: 2
    Dernier message: 25/07/2005, 17h24
  3. Performance des vertex array
    Par Mathieu.J dans le forum OpenGL
    Réponses: 13
    Dernier message: 25/06/2004, 10h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo