2010-09-15 9 views
4

J'ai un code Haskell qui utilise beaucoup de String, tout en le montrant, il semble que le code utilise beaucoup de mémoire pour stocker les listes []. Une solution à ce problème est d'utiliser Data.ByteString.Lazy au lieu de cordes, maisComment passer de String à Data.ByteString.Lazy dans un code Haskell existant?

ce que je dois prendre soin de tout en faisant cela,

quelle partie du code doivent être examiner attentivement: pli, carte, ...?

merci pour la réponse

+0

BTW, Vous pouvez motiver les gens à répondre à vos questions si vous cochez une réponse par question acceptée en cochant le signe accepté – fuz

Répondre

2

Il faut savoir, que ByteString est vraiment mauvais pour des choses comme itération dessus des éléments, mais mieux pour Concatation, etc.

Si vous voulez travailler avec des chaînes ordinaires, vous avez pour convertir la chaîne à un ByteString, il suffit de faire quelque chose comme

import Data.ByteString.Lazy as B 

et coller une B devant chaque fonction qui fonctionne avec eux - la plupart des fonctions pour String existe aussi ByteString. Veuillez noter - vous devez convertir les chaînes que vous utilisez en ByteString avec certaines fonctions.

Si vous utilisez Data.ByteString.Lazy.Char8 à la place, vous pouvez facilement utiliser pack, mais tous les caractères supérieurs à 255 seront tronqués. En outre, ce type est plus approprié pour la mémoire de données binaires et de coffres-forts.

Editer: Vous devriez envisager d'utiliser le texte du package si vous souhaitez travailler sur des chaînes de texte. Regardez here pour plus de détails.

+2

Pourquoi ByteString est-il "vraiment mauvais pour des choses comme l'itération"? Il se résume à un vecteur de 8 bits ints; exactement comme un C 'char *'. 'map' sur strict Bytestrings fait une seule allocation pour le vecteur cible, lit chaque octet du vecteur source, applique les fonctions de mappage et met le résultat en mémoire. Tout est déballé. C'est sujet à la fusion de flux. Je ne peux rien imaginer de meilleur pour l'itération que ça! – jrockway

+0

C'est ce que l'on pensait à l'école. – fuz

+0

Comme je pense, il implique beaucoup de copie de tableau si vous ajoutez/supprimez des éléments (en particulier l'ajout) de la tête d'un ByteString. Mais oui, je peux me tromper. – fuz

5

L'extension OverloadedStrings peut être utile si vous utilisez GHC et que vous convertissez du code avec beaucoup de littéraux de chaîne. Il suffit d'ajouter ce qui suit en haut de votre fichier source:

{-# LANGUAGE OverloadedStrings #-} 

Et vous ne devez pas utiliser B.pack sur toutes les chaînes littérales dans votre code. Vous pourriez avoir les éléments suivants, par exemple:

equalsTest :: B.ByteString -> Bool 
equalsTest x = x == "Test" 

Sans l'extension cela donnerait une erreur, puisque vous ne pouvez pas utiliser == sur un ByteString et un [Char]. Avec l'extension, les littéraux de type chaîne ont le type (IsString a) => a et ByteString est une instance de IsString, donc "Test" est saisi ici comme ByteString et il n'y a pas d'erreur.

+0

J'ai aussi pensé à suggérer celui-ci, mais comme il s'agit d'une extension de langage, cela peut casser la portabilité. – fuz

+3

Les gens qui écrivent des logiciels dans Haskell utilisent autre chose que GHC? Oh. – jrockway

+0

Oui, en effet. Par exemple, il y a le compilateur Utrecht Haskell, m'a-t-on dit, qui peut parfois créer du code plus rapidement. – fuz