2010-01-27 8 views
3

Dans mon projet, où j'ai adopté l'algorithme Aho-Corasick pour faire un certain mode de filtrage des messages côté serveur, le message reçu par le serveur est une chaîne de caractères multi-octets. Mais après plusieurs tests, j'ai trouvé que le goulot d'étranglement est la conversion entre une chaîne mulitbyte et un wstring unicode. Ce que j'utilise maintenant, c'est la paire de mbstowcs_s et wcstombs_s, qui prend près de 95% du coût en temps du mode entier. En outre, j'ai essayé MultiByteToWideChar/WideCharToMultiByte, il a obtenu exactement le même résultat. Alors, je me demande s'il existe une autre façon plus efficace de faire le travail? Mon projet est construit en VS2005, et la chaîne convertie contiendra des caractères chinois. Merci beaucoup.Y a-t-il même une implémentation rapide de la chaîne de caractères multi-octets convertie en unicode wstring?

Répondre

0

Déconseillé (je crois) mais vous pouvez toujours utiliser les versions non sécurisées (mbstowcs et wcstombs). Je ne sais pas si cela aura une nette amélioration cependant. Alternativement, si votre jeu de caractères est limité (a - z, 0 - 9, par exemple), vous pouvez toujours le faire manuellement avec une table de recherche ..?

+0

Malheureusement, le jeu de caractères doit prendre en charge de nombreux autres caractères tels que le chinois. Et aussi j'ai essayé mbstowcs, le résultat est juste le même. – Avalon

0

Peut-être pouvez-vous réduire le nombre d'appels à MultiByteToWideChar?

+0

Lorsque vous cochez un message, il suffit d'appeler une seule fois MultiByteToWideChar pour qu'il ne puisse plus être réduit. – Avalon

+0

Pouvez-vous combiner plusieurs messages dans un tampon plus grand, puis l'appeler? –

+0

La logique nécessite le processus de filtrage dès que possible. – Avalon

0

Vous pourriez également adopter Aho-Corasick pour travailler directement sur des chaînes multi-octets.

+0

La version originale de AC est pour ASCII, alors je le fais pour soutenir le caractère large. Parce que le caractère de multi-octets peut contenir un char ou deux, compte tenu du ca dépend de la machine d'état, je ne suis pas sûr de savoir comment changer l'algorithme AC pour travailler sur cela. – Avalon

+0

Droite. Je voulais dire que vous pouviez inclure dans la machine d'état des connaissances sur la largeur de chaque caractère, de sorte que le système interne et la machine à états soient conscients du nombre d'octets à sauter pour chaque caractère. Certes, ce n'est pas trivial. – Avi

+0

Merci, j'ai modifié le code original pour prendre en charge les caractères multi-octets avec un certain tour. Maintenant, cela a bien fonctionné. – Avalon

1

Il existe un certain nombre de possibilités.

Premièrement, qu'entendez-vous par "caractère multi-octet"? Voulez-vous dire UTF8 ou un système ISO DBCS? Si vous regardez la définition de UTF8 et UTF16, il est possible de faire une conversion hautement optimisée, en extrayant les bits "x" et en les reformatant. Voir par exemple http://www.faqs.org/rfcs/rfc2044.html parle de UTF8 < ==> UTF32. Ajuster pour UTF16 serait simple.

La deuxième option pourrait être de travailler entièrement en UTF16. Rendre votre page Web (ou UI Dialog ou autre) en UTF16 et obtenir l'entrée de l'utilisateur de cette façon.

Si tout le reste échoue, il existe d'autres algorithmes de chaîne que Aho-Corasick. Recherchez éventuellement un algorithme qui fonctionne avec votre encodage d'origine.

[Ajouté 29-Jan-2010] Voir http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt pour plus d'informations sur les conversions, y compris deux implémentations C de mbtowc() et wctomb(). Ceux-ci sont conçus pour fonctionner avec wchar_ts arbitrairement grand. Si vous avez juste wchar_ts 16 bits alors vous pouvez le simplifier beaucoup.

Celles-ci seraient beaucoup plus rapides que les versions génériques (sensibles à la page de codes) dans la bibliothèque standard.

+0

Merci Michael, je vais essayer ce nouveau mbtowc/wctomb. – Avalon