chaîne de caractères.substring vs chaîne.prendre
Si vous voulez seulement de prendre une partie d'une chaîne, sous-chaîne de la méthode est le plus souvent utilisé.
Cela a un inconvénient que vous devez d'abord tester sur la longueur de la chaîne afin d'éviter des erreurs.
Par exemple, vous voulez enregistrer les données dans une base de données, et que vous voulez couper une valeur de 20 caractères.
Si vous n'temp.substring(0,20) mais temp ne contient 10 caractères, une exception est levée.
Il y a 2 solutions que je vois :
- test sur la longueur, et de faire de la sous-chaîne si nécessaire
-
utiliser l'extension de la méthode Prendre
string temp = "1234567890"; var data= new string( temp.Take(20).ToArray()); --> data now holds "1234657890"
Est-il un inconvénient en termes de vitesse ou de l'utilisation de la mémoire , lorsque l'on utilise la méthode de Prendre.
L'avantage est que vous n'avez pas à écrire à tous ceux si les déclarations.
- Utiliser un Chronomètre pour effectuer des synchronisations. Aussi, vous pouvez écrire votre propre méthode d'extension de chaîne qui ne peut le vérifier.
- Je dirais que Prendre énumérer votre Chaîne. Cela peut faire une grande différence avec de longues cordes.
- La Performance est tellement Contextuel.
temp.SubString(0, Math.Min(20, temp.Length))
Vous devez vous connecter pour publier un commentaire.
Si vous vous retrouver à faire beaucoup, pourquoi ne pas écrire une méthode d'extension?
Par exemple:
Comme Henk Holtermand dit,
Take()
crée unIEnumerator
et puis vous avez besoin de laToArray()
appel.Donc, si l' performance est important dans votre application, ou vous allez effectuer des sous-chaînes à plusieurs reprises dans vos processus, le rendement pourrait être un problème.
J'ai écrit un exemple de programme de référence exactement comment plus lent est le
Take()
méthode voici les résultats:Testé avec dix millions de fois:
Et voici le code:
substring
/take
avec un peu plus de l'entropie. Les résultats suggèrentTake
est 6 à 10 fois plus lent, mais toujours très rapide (moins de 0.0008 ms partake
).Tout d'abord, je ne voulais pas répondre (comme il y a déjà des réponses valables), mais je voudrais ajouter quelque chose qui ne rentre pas comme un commentaire:
Vous parlez de la performance /des problèmes de mémoire. La droite. Comme les autres ont dit,
string.SubString
est bien plus efficace, car de la façon dont il est à l'intérieur optimisé et parce que de la façon dont LINQ fonctionne avecstring.Take()
(énumération de caractères, etc...).Ce que personne ne dit, c'est que le principal inconvénient de
Take()
dans votre cas est que il a totalement détruit la simplicité d'une sous-chaîne. Tim dit, pour obtenir la chaîne que vous voulez, vous aurez à écrire:Putain... c'est tellement plus difficile à comprendre qu' (voir Matthieu de la méthode d'extension):
LINQ est grande pour beaucoup de cas d'utilisation, mais ne doit pas être utilisé si pas nécessaire. Même une simple boucle est parfois mieux (c'est à dire plus rapide, plus lisible/compréhensible) que LINQ, alors imaginez pour un simple sous-chaîne...
Pour résumer LINQ dans votre cas:
public static string StringJoin(this IEnumerable<char> chars) { return new string(chars.ToArray()); }
Et de l'utiliser ensuite comme suit:string myString = temp.Take(20).StringJoin();
Si c'est de la lisibilité, alors je pense que cette solution est tout à fait élégante, sinon le LINQ est beaucoup trop lent en comparaison avecSubstring
Une variation de @Daniel réponse qui me paraît plus juste.
un Guid de la longueur est de 36. Nous sommes en train de créer une liste avec une longueur variable de chaînes de 1 à 36, et nous allons viser pour la prise de 18 ans avec l'
substring
/take
méthodes, de sorte que près de la moitié ira de travers.Les résultats que j'obtiens suggèrent que
Take
sera 6 à 10 fois plus lent queSubstring
.Exemple de résultats :
donc, pour 5 millions de chaînes, en faisant à peu près 2,5 millions d'opérations, le temps total est 2,1 secondes , ou autour de 0.0008564 millisecondes = ~ 1 micro seconde par opération. Si vous sentez que vous avez besoin de la couper en 5 pour la sous-chaîne, allez-y, mais je doute que dans la vie réelle, en dehors de collants de la boucle, vous allez jamais sentir la différence.
Oui.
Take()
implique la création d'unIEnumerator<char>
première et, pour chaque char, en passant par les cercles deMoveNext()
etyield return;
etc. Notez également la ToArray et la chaîne de constructeur.Pas un problème pour un petit nombre de chaînes de caractères, mais dans une grande boucle spécialisées fonctions de chaîne sont beaucoup mieux.
La
Take
méthode d'extension ne crée pas de sous-chaîne, elle renvoie une requête qui peut être utilisé pour créer unChar[]
(ToArray) ou unList<Char>
(ToList). Mais vous voulez vraiment avoir cette sous-chaîne.Alors vous avez besoin d'autres méthodes:
Cette implicitement utilise un
foreach
pour énumérer les caractères, crée un nouveau char[] (ce qui pourrait allouer trop de taille en raison du doublement de l'algorithme). Enfin une nouvelle chaîne est créé à partir de lachar[]
.La
Substring
d'autre part utilise méthodes optimisées.De sorte que vous payez ce petit commodité avec la mémoire qui pourrait être négligeable, mais pas toujours.