Création de grandes strings
Bonjour,
Dans iPocket Draw, j'envoie les dessins par mail sous forme de fichier texte dans le corps du message.
Ca fonctionne mais seulement avec peu d'objets surtout en DXF.
Je voie avec Instruments que pour générer un fichier texte final de 32 Ko j'ai un pic d'occupation mémoire de 22 Mo (dans le simulateur) !
Et sur mon iPhone ça coince avec un gros crash...
Je construit le fichier texte avec plein de monTexte = [monTexte stringByAppendingString:@xxxx\n];
Je soupçonne que cela n'est pas la meilleure solution vu le résultat.
Des avis éclairés me seraient bd'un grand secours.
Merci
Eric
Dans iPocket Draw, j'envoie les dessins par mail sous forme de fichier texte dans le corps du message.
Ca fonctionne mais seulement avec peu d'objets surtout en DXF.
Je voie avec Instruments que pour générer un fichier texte final de 32 Ko j'ai un pic d'occupation mémoire de 22 Mo (dans le simulateur) !
Et sur mon iPhone ça coince avec un gros crash...
Je construit le fichier texte avec plein de monTexte = [monTexte stringByAppendingString:@xxxx\n];
Je soupçonne que cela n'est pas la meilleure solution vu le résultat.
Des avis éclairés me seraient bd'un grand secours.
Merci
Eric
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Boucle
{
NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];
Boucle
monTexte=[monTexte stringByAppendingString:@xxxx\n];
Fin de Boucle
// retain sur ce qui doit l'être (schlum addendum)
[pool release];
}
Fin de Boucle
Dans ce schéma, les strings créées sont éliminées plus rapidement, au détriment sans doute de la rapidité. Là il faut arbitrer rapidité/empreinte mémoire
C'est pas malin du tout comme technique... À chaque fois ça met un nouvel objet NSString dans la mémoire "autoreleased" qui n'est libérée qu'une fois par passage dans la runloop.
Pourquoi ne pas utiliser un NSMutableString et faire des "appendString" sur le même à chaque fois ?
T'as pas oublié un "retain" quelque-part dans ta technique ?
Parce que là t'as plus rien du tout après ton "pool release", "monTexte" pointe sur un objet inexistant.
Si après la première boucle, je donnais un schéma, pas du code.
Le côté intéressant de la question était pour moi était dans le problème de la gestion de beaucoup d'instances intermédiaires, et comment faire pour s'en débarasser. D'où la méthode proposée.
Mais je confirme la grande sagesse de Schlum, Eric, utilise une NSMutableString sans créer d'instance intermédiaire. Et si tu es obligé de créer des instances intermédiaires, utilise la technique de l'autorelease pool.
Je teste ça dans la journée et je vous dirais le gain (en mémoire) réalisé.
Mais je dois avouer que je n'ai pas bien compris la différence entre NSString et NSMutableString.
En relisant la doc., c'est vrai que NSMutableString a des méthodes intéressantes, genre appendstring qui est tout à fait ce qui me faut.
Et effectivement si à chaque "monTexte=[monTexte stringByAppendingString:@xxxx\n];" cela crée une nouvelle NSSTring, je devais en avoir un tas...et de taille croissante en plus.
A plus tard.
Eric
NSMutableString = chaà®ne de longueur variable, et de contenu variable
Par derrière, Foundation doit faire du hachage à ta place pour les NSMutableString, alors que pour NSString il réagit en fonction de la longueur de la chaà®ne.
Le résultat est très impressionnant.
Avec les "monTexte=[monTexte stringByAppendingString:@xxxx\n];" je passais d'environ 740 Ko à un pic à 22 Mo.
Avec les NSMutableString et appendstring, je monte, pour créer le même fichier, à 825 Ko !!!
Bonne journée à tous.
Eric
Tout à fait, quand on utilise beaucoup les objets "autoreleased", il faut gérer des pools dans les "scopes" intermédiaires...
C'est très bien expliqué ici :
http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html
C'est encore plus vrai sur les plate-formes embarquées très sensibles à la mémoire résiduelle.
C'est normal, tu n'utilises pas du tout le pool d'"autorelease" et d'objets temporaires, donc tu consommes pile poil la mémoire qu'il faut (peut-être à un chouilla près, je ne sais pas comment NSMutableString gère ses allocations en interne).
En plus, ça doit être plus rapide, car largement plus optimisé.
Encore merci.
Eric