-1
votes

C # Supprimer les retours de chariot, les pauses de ligne et les espaces blancs de la chaîne aussi efficace que possible

en C # J'ai une chaîne contenant des espaces blanchisseurs, des retours de chariot et / ou des pauses de ligne. Y a-t-il un moyen simple de normaliser de grandes chaînes (100 000 à 1 000 000 caractères) qui sont importées de TextFiles comme efficace que possible?

Pour clarifier ce que je veux dire: disons que ma chaîne ressemble à String1 Mais je veux que ce soit comme String2 xxx


8 commentaires

Qu'est-ce que tu as essayé jusque-là?


J'ai essayé des expressions régulières qui se sentaient lentement, c'est pourquoi j'ai demandé une manière efficace.


@MikeBeaton L'approche donnée dans le lien est utile lorsque vous appelez la repensation à plusieurs reprises, mais plutôt que cela, j'ai une grande chaîne, c'est pourquoi ma question est différente à mon avis ..


D'accord. FYI Je n'ai pas officiellement marqué cela comme un duplicata et fermez-le - quelqu'un d'autre de cela doit avoir - je viens d'ajouter le commentaire pour vos informations supplémentaires!


@Mikebeaton oui je sais, mais merci pour l'information et votre réponse, ce qui m'a aidé à résoudre un autre problème pour résoudre des aswell ;-)


Cela compte beaucoup combien de temps vos cordes sont réellement. J'ai fait une base comparative et autour des caractères 10_000 marquez une méthode parallèle lancée surperformant la méthode , une fois la marque de caractères 100_000_000, la version parallèle était un peu supérieure à 15 fois plus rapide (également comparé avec un benchmarkdototnet).


@Knoop voulez-vous que je spécifie cela dans la question? Les cordes que j'ai entre 10 000 et 100 000 caractères.


Avec ces longueurs, vous avez une bonne chance une méthode parallèle exercera la réponse acceptée, mais cela dépend également du matériel qu'il s'exécute. Les problèmes d'optimisation et d'efficacité sont rarement simples en avant. Donc, si la réponse acceptée est assez rapide, j'irais juste avec cela (aussi du point de vue qu'il est préférable d'éviter une optimisation prématurée)


4 Réponses :


0
votes
var input = " ab c\r\n de.\nf";
var result = Regex.Replace(input, @"\s+", "");

// result is now "abcde.f"
You can see it in action here

2 commentaires

Merci pour votre réponse! Mais utilise des expressions régulières la voie la plus efficace?


C'est assez efficace!



0
votes

Vous pouvez faire comme ça. Vous pouvez définir les caractères spéciaux que vous souhaitez autoriser dans un fichier de configuration. Dans mon cas, j'ai défini dans Appseinttings.json File. XXX


3 commentaires

Merci de votre réponse, mais j'espérais trouver un moyen plus simple de le faire.


Probablement mieux de faire un hashset à partir des autoratactes autorisés (en fonction de ce qui est là) mais aussi probablement mieux de définir une liste noire plutôt que d'un blancheur


@ pinkfloydx33 merci, c'est un point valide



1
votes

Pour ce faire efficacement, vous souhaitez éviter le regEx et conserver des allocations de mémoire au minimum: Ici, j'ai utilisé un tampon de caractères bruts (plutôt qu'un stringbililater ) et pour pour plutôt que foreach pour optimiser l'accès à chaque caractère: xxx


8 commentaires

Peut-être préférable d'utiliser quelque chose comme Char.iswhitepace et Char.Control depuis que je suppose qu'ils veulent tout l'espace blanc / non imprimable enlevé


Je ne peux pas accepter que pour sera plus efficace. Je dirais même que pour sera plus lent en raison de l'optimalisation que le compilateur peut faire avec foreach


@strenat - foreach impliquera un appel pour obtenir un énumérateur (probablement une structure), puis un appel movenext pour chaque itération et un appel à actuel pour obtenir la valeur réelle . La mise en œuvre vient alors de saisir le caractère de l'index spécifié. Tout cela pourrait être optimisé, mais ce n'est peut-être pas.


Je pense que vous sous-estimez quelle optimalisation de compilateur peut faire. Vérifiez-le vous-même: DotNetFiddle.net/gr6knh


@strenat - merci pour le lien. Toutefois, si vous échangez les appels sur de référence autour de celui que vous faites stripforeach en premier, suivi de bande alors vous trouverez que Bande fonctionne plus vite! : DotNetFiddle.net/btrsxt


@strenat Commuez-les et les résultats sont inversés en faveur du pour , vérifiez-le vous-même: DotNetFiddle. NET / M12LWH . Donc, en d'autres termes, pas une bonne référence. Avez-vous une théorie / documentation réelle pour remonter ainsi? Dernièrement, je sais que l'optimisation du compilateur fait en réalité en cas de foresach sur un tableau est itération au lieu d'utiliser un énumérateur, ce qui le rend presque aussi rapide que pour


Vous avez raison, il semble que le premier appel soit toujours plus lent sur ce banc. Mais ne semble toujours pas que la ni la netteté ne soit plus rapide.


Lorsque je l'exécute avec BenchmarkDototnet, le résultat était le suivant: bande | 36.42 NS | 0.389 NS | 0.363 ns striptforeach | 27.83 NS | 0.488 NS | 0.457 ns , semble être toujours foreach est meilleur



3
votes

Le terme "efficacement" peut fortement dépendre de vos cordes et de vos chiffres. Je suis arrivé avec la prochaine référence (pour Benchmarkdototnet ): XXX < P> Ceci donne sur ma machine: xxx


6 commentaires

Merci pour votre réponse géniale! Si j'interprète cela de la bonne façon, cela signifie que l'approche de @Sean est la plus rapide jusqu'à présent. Ai-je raison?


@Daniel Yep. Mais encore une fois, vous devriez tester une charge de travail réelle.


Étant donné que OP a déclaré que l'optimisation souhaitée est spécifiquement destinée aux grandes chaînes OMI, une bonne référence devrait représenter cela. Certaines solutions pourraient avoir plus de surcharge de startups, mais être plus rapides sur une base de caractères, ce qui les fait perdre sur des cordes courtes, mais sortez devant des cordes très longues.


@Knoop terme "grand" est très large, c'est pourquoi j'ai suggéré de tester (banc) contre la charge de travail réelle (et du matériel actuel). Potentiellement, la fréquence même de caractères spécifiques peut affecter les performances d'une ou une autre solution.


@Gurustron, puisque nous avons .NET CORE 3.1, pourriez-vous ajouter une version foreach dans le résultat du test? Vous pouvez le copier à partir d'ici: DotNetFiddle.net/gr6knh


@strenat ajouté comme vous l'avez demandé.