2011-09-12 5 views
0

J'ai des problèmes de mémoire avec les iPhones de génération antérieure (ipod touch 1st gen, 2nd gen e.t.c). Cela est dû à la quantité de mémoire allouée lorsque je charge et stocke un dictionnaire de mots de 170k.Mémoire efficace et rapide Stockage/Accès au dictionnaire iPhone/Android

Ce code (très simple):

string[] words = dictionaryRef.text.Split("\n"[0]); 
_words = new List<string>(words); 

Cette alloue au démarrage autour de 12 Mo de stockage, iPhone a autour Je pense que 43MB. Alors que + textures + sons + l'OS il a tendance à se casser.

Vitesse sage, l'accès en utilisant une recherche binaire est très bien. Mais le stocker dans la mémoire plus efficacement (et le charger plus efficacement).

Le texte.Split semble prendre beaucoup de mémoire de tas.

Un conseil?

+0

Qu'est-ce que '" \ n "[0]'? Ne pourriez-vous pas utiliser '\ n'? – jv42

+1

Une vraie question maintenant: pourquoi avez-vous besoin d'une liste au lieu d'un tableau simple? – jv42

+0

J'estime que 170 000 mots avec (en moyenne une surestimation) de 10 caractères (à un octet chacun) ne devraient occuper qu'environ 1,7 Mo. Stocker les données sous la forme d'un tableau de tableaux char ne devrait occuper que peu de mémoire. –

Répondre

0

Vous ne pouvez pas compter trop sur la quantité de mémoire disponible pour ces périphériques pré-3.0 au démarrage. 43 Mo est plutôt optimiste. Est-ce que votre application vérifie simplement si le mot est dans la liste ou non? Vous pourriez vouloir rouler votre propre table de hachage au lieu d'utiliser une recherche binaire. Je chercherais une partie de la littérature et de la pile de débordement pour trouver des moyens efficaces pour stocker un grand dictionnaire avec les tailles de mots particuliers que vous avez. Une recherche google sur table de hachage pourrait vous donner une meilleure implémentation.

+0

Ce n'est pas la mémoire de stocker la liste de sa mémoire utilisée alors qu'il est divisé en mots. La recherche est une bonne vitesse sinon. Une table de hachage utiliserait simplement plus de mémoire globale. J'ai besoin d'une meilleure méthode pour scinder la chaîne en mots en fonction du délimiteur (nouvelle ligne). – Ash

+0

Votre arbre binaire utilise de la mémoire car il doit contenir tout l'arbre en mémoire. Si vous utilisez une table de hachage, une fois que vous avez inséré le mot dans la table, vous n'avez pas besoin de conserver tous les nœuds pour effectuer une recherche binaire, et une recherche de hachage devrait être presque aussi efficace, sinon plus. La clé est de sélectionner un bon algorithme de hachage qui fonctionne bien avec vos données proposées. –

0

Utilisez SQLite. Il utilisera moins de mémoire et sera plus rapide. Créez un index sur votre colonne de mots et voila, vous avez une recherche binaire, sans avoir le dictionnaire entier chargé en mémoire.

0

D'abord si dictionaryRef.text est une chaîne de caractères (et il semble donc) alors vous avez déjà quelque chose d'énorme étant alloué (2 octets par caractères). Vérifiez que cela peut représenter une grande quantité (près de la moitié) de la mémoire totale allouée. Vous devriez penser à mettre en cache ceci (l'idée de base de données est bonne, mais un fichier pourrait faire pour utiliser ensuite File.ReadAllLines dans une future exécution).

Ensuite, vous pouvez essayer de faire un peu mieux que la méthode Split de Mono. Il crée une liste et la transforme ensuite en un tableau (en appelant ToList) à la fin - dont vous finissez par créer une nouvelle liste. Puisque votre exigence (seulement '/ n') est assez basique, je vous suggère de lancer votre propre méthode Split (ou de copier/coller/réduire celle de Mono) et d'éviter les allocations de mémoire temporaires.

Dans tous les cas prendre beaucoup de (mémoire) des mesures depuis des allocations, encore plus pour les chaînes, cela arrive souvent où on ne regarde pas ;-)

0

je serais d'accord avec Morningstar que l'utilisation d'un back-end SQLite pour votre stockage de mots semble être la meilleure solution à ce que vous essayez de faire.

Cependant, si vous insistez sur l'utilisation d'une liste de mots, voici une suggestion:

Il me semble que dictionaryRef.text est construit en lisant un fichier texte dans son intégralité (File.ReadAllText() ou quelque). Au lieu de cela, pourquoi ne pas utiliser TextReader.ReadLine() pour lire 1 mot à la fois du fichier dans une liste, évitant ainsi d'utiliser String.Split() et d'utiliser des tonnes d'espace de stockage temporaire?

En fin de compte cela semble être ce que vous voulez de toute façon ... et ReadLine() va se scinder sur \ n pour vous.

Questions connexes