Représentation des données

KyoKyo Membre
08:28 modifié dans API UIKit #1
Hello ici,

Je ne savais pas trop où poster donc je tente ma chance ici. J'aurais une question d'ordre général à  vous soumettre.

J'utilise actuellement sur le projet sur lequel j'ai décidé d'utiliser une plist (système de dictionnaire/tableau). Plus je code, plus la représentation des données devient complexe. Donc je me demande si le choix d'utiliser une plist est judicieux.

Pour essayer de le représenter :

tableau -> elem0 [dict] -> title [string]
                elem1 [dict]    sequences [tab] -> elem0 [dict] -> etc...
                elem2 [dict]    items [tab]            elem1 [dict]
             
Je crois pas être clair mais voilà  un exemple de ma représentation des données et ça continue sur 10 niveaux à  peu près voire plus suivant mes besoins. Donc, j'ai mon modèle qui se charge de construire/charger un gros dictionnaire, les controlleurs se chargent eux de transmettre une partie de ce dictionnaire.

J'ai entendu sur une vidéo de cours de stanford que les plist n'était plus conseillées dès qu'elles dépassaient une certaine taille (une centaine de ko), bon avec mon anglais, j'ai pas vraiment tout saisi.

De manière plus général, comment représentez-vous vos données ? codés en dur (ouch), xml/plist, base de données, autres ? (Avantages et inconvénients ?)

Have fun !

Réponses

  • Philippe49Philippe49 Membre
    juillet 2009 modifié #2
    • Les property lists ont l'avantage d'être assez facile à  remplir via l'interface de XCode, ou le Property List Editor. Cependant, cela se complique si on veut stocker des objets autres que NSArray, NSData, NSDictionary, NSString, NSNumber et NSDate .

    • iPhone SDK3 fournit également SQLite, efficace pour le stockage et la recherche (en local) si la quantité de données est importante.

    • L'archivage/désarchivage des données actuellement traitées avec des méthodes comme encodeWithCoder: ou decodeWithCoder:  plus pertinentes pour une application qui échange des informations avec l'utilisateur. De plus cela permet d'archiver tout type de données, des images, des couleurs, ... y compris des objets non standards déclarés par ton programme.

    • Les fichiers traditionnels : on peut stocker, ouvrir, transformer  dans des fichiers  du SandBox avec les méthodes classiques du C.

    • XML avec NSXMLParser.

    • Coredata qui est une version automatisée pour la persistence des documents, soit pour des applications ultra-simples, soit pour des programmeurs aguerris dans les cas plus compliqués.


    Le elem0 qui apparaà®t deux fois dans ton schéma, c'est le même objet ?
  • KyoKyo Membre
    08:28 modifié #3
    Merci pour les précisions !

    Non les elem0 ne sont pas nécessairement les mêmes objets.

    J'ai justement utilisé les plist car simple à  remplir depuis xcode, ça m'a permis d'avancer rapidement dans mon code. L'image des données que je manipule est la même que celle de la plist. J'ai à  la base mis en place le pattern builder pour créer mes données (dictionnaire) à  partir de plist (un simple chargement), base de données, xml, etc...

    Ma question pourrait être vu autrement comme :
    1/ Vaut-il mieux se trimballer un gros dictionnaire (qui se réduira au fur et à  mesure que l'on avance dans les vues). En gros je suis dans la vue1 qui a chargé le dico en entier, en cliquant un bouton pour aller sur la vue2, je ne lui transmet qu'une partie du dico, ainsi de suite.
    2/ Ou vaut-il mieux dans la vue1 charger le minimum nécessaire, puis en cliquant sur un lien pour aller sur la vue2, le chargement de de cette dernière va aller chercher les données nécessaire à  son fonctionnement dans une base de données ou autre ?

    Quand j'y avais réfléchi, le fait d'avoir une représentation des données fixe me permettait d'implémenter mon code indépendamment de la source de données (le cas 1/). A priori mes sources seraient du xml, j'aurais alors à  implémenter plus tard un parser de xml qui va construire mon dico.
    La solution 2/ a l'air plus optimisée, j'ai pas fait de test mais j'avais noté un petit temps de chargement des fois pour passer d'une vue à  l'autre (sachant que j'ai implémenté le 1/ pour l'instant) mais ça je pense que ça peut s'améliorer.
  • Philippe49Philippe49 Membre
    08:28 modifié #4
    dans 1247151723:

    1/ Vaut-il mieux se trimballer un gros dictionnaire (qui se réduira au fur et à  mesure que l'on avance dans les vues). En gros je suis dans la vue1 qui a chargé le dico en entier, en cliquant un bouton pour aller sur la vue2, je ne lui transmet qu'une partie du dico, ainsi de suite.


    Tu charges les données une fois pour toutes. En passant de la vue 1 à  la vue 2, tu ne charges plus rien : tu transmets simplement  au view controller n°2 un pointeur vers la partie du Model qui l'intéresse.


  • Philippe49Philippe49 Membre
    08:28 modifié #5
    Un petit essai sur l'encombrement mémoire des plist : un facteur 3 à  priori


    % gcc pgm.m -o pgm -framework Foundation
    % pgm
      data (Ko)    |    plist (Ko)  | rapport plist / data


          0.17    |        0.54    |    3.24
          0.66    |        1.94    |    2.93
          2.66    |        7.57    |    2.85
        10.62    |      30.07    |    2.83
        42.50    |      120.07    |    2.83
        170.00    |      480.07    |    2.82
        680.00    |    1920.07    |    2.82
      2720.00    |    7680.07    |    2.82
      10880.00    |    30720.07    |    2.82
      43520.00    |  122880.07    |    2.82
    174080.00    |  491994.44    |    2.83
    %


    et le code du test
    <br />#import &lt;Foundation/Foundation.h&gt;<br /><br />int main (int argc, const char * argv&#91;]) {<br />	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];<br />	NSMutableArray * array = [NSMutableArray array];<br />	int i,N;<br /><br />	puts(&quot;&nbsp; data (Ko)&nbsp; &nbsp; |&nbsp; &nbsp; plist (Ko)&nbsp; | rapport plist / data&quot;);<br />	puts(&quot;-----------------------------------&quot;);<br />	for(N=10;N&lt;(1&lt;&lt;24);N*=4) {<br />		for(i=0;i&lt;N;i++){<br />			NSString * string = [NSString stringWithFormat:@&quot;string&nbsp; n %07d&quot;,i];<br />			[array addObject:string];<br />		}<br />		<br />		NSString * path=[NSHomeDirectory() stringByAppendingPathComponent:@&quot;Desktop/bidule.plist&quot;];<br />	<br />	<br />		if(![array writeToFile:path atomically:YES]) {<br />			puts(&quot;ça coince&quot;);<br />		} else {<br />			FILE * pf=popen(&quot;wc -c bidule.plist&quot;,&quot;r&quot;);<br />			unsigned int size;<br />			fscanf(pf,&quot;%u&quot;,&amp;size);<br />			pclose(pf);<br />			printf(&quot; %9.2f&nbsp; &nbsp;  |&nbsp;  %9.2f&nbsp; &nbsp; |&nbsp; &nbsp; %.2f&#092;n&quot;,N*strlen(&quot;string&nbsp; n 0000000&quot;)/1024.,(double)size/1024.,(double)size/(N*strlen(&quot;string&nbsp; n 0000000&quot;)));<br />		}<br />	}<br />	[pool drain];<br />	return 0;<br />}
    
  • KyoKyo Membre
    08:28 modifié #6
    Là , ça serait plus de l'optimisation.

    Mais que se passerait-il dans le cas où les données à  charger en une fois serait vraiment importante. Ou plutôt avec cette manière de faire, à  partir de quelle moment verrait-on une baisse des performances ?

    Edit: Merci pour le test de l'encombrement.
  • Philippe49Philippe49 Membre
    08:28 modifié #7
    Le cas existe : une appli de photos ou de musiques par exemple. Dans ce cas, chaque donnée brute est dans un fichier séparé et le dictionnaire principal ne stocke que des références par une arborescence dont les feuilles sont des NSString. Il faut trouver le bon compromis selon ton application.

    Quand à  la mesure exacte, il faudrait faire/trouver des évaluations ...
  • Philippe49Philippe49 Membre
    08:28 modifié #8
    Réflexion glanée sur un autre forum pour l'occupation mémoire :

    "Well, as far as I can tell, Apple has santioned off about 24MB of main memory for us developers out of its total physical memory."

    Effectivement, j'ai fait apparaà®tre dans une de mes applications des pics de 20 Mo, avec un temps d'attente associé, sans buz. Cependant, on voit également des posts qui s'étonnent de Memory Warning aux alentours de 4 Mo ...



  • AliGatorAliGator Membre, Modérateur
    08:28 modifié #9
    dans 1247157678:

    Réflexion glanée sur un autre forum pour l'occupation mémoire :

    "Well, as far as I can tell, Apple has santioned off about 24MB of main memory for us developers out of its total physical memory."

    Effectivement, j'ai fait apparaà®tre dans une de mes applications des pics de 20 Mo, avec un temps d'attente associé, sans buz. Cependant, on voit également des posts qui s'étonnent de Memory Warning aux alentours de 4 Mo ...
    Au passage, cette info là  chez m4e peut être intéressante aussi.
    Avant le 3GS on avait en gros 40Mo de RAM de dispo en enlevant aux 128Mo la RAM prise par le système, les daemons Apple, et les applis intégrées. Maintenant on a de l'ordre de 156Mo avec le 3GS de dispo pour "nos apps"...
  • Philippe49Philippe49 Membre
    juillet 2009 modifié #10
    dans 1247154532:

    Un petit essai sur l'encombrement mémoire des plist : un facteur 3 à  priori


    Ce qui se confirme en observant le fichier lui-même, le facteur 3 venant essentiellement des balises.
    Un fichier XML classique ne doit pas être plus économique.


    % head -11 bidule.plist
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">;
    <plist version="1.0">
    <array>
    <string>string  n 0000000</string>
    <string>string  n 0000001</string>
    <string>string  n 0000002</string>
    <string>string  n 0000003</string>
    <string>string  n 0000004</string>
    <string>string  n 0000005</string>
    <string>string  n 0000006</string>



  • KyoKyo Membre
    08:28 modifié #11
    Merci pour ces informations qui me seront utiles.

    Ali, ça veut dire dire que certaines applis qui tournent bien sous 3GS rameront/planteront sur 3G c'est ça ?
  • Philippe49Philippe49 Membre
    08:28 modifié #12
    C'est quoi la taille de tes données ?
  • KyoKyo Membre
    08:28 modifié #13
    Actuellement, si je regarde la taille de ma plist, ça donne 68ko mais je n'ai pas rempli tous les champs, je pense que ça devrait atteindre 100ko quand ça sera fait.

    Ca c'est en gros ce que fait le premier elem0 de mon petit schéma en haut. Sachant que mon tableau contient 5 éléments, on va dire qu'en tout ça doit faire 500ko mais dans l'absolu le tableau contient un nombre arbitraire d'éléments. J'envisage de faire un plist par élément et ne charger que par bloc de 100ko quand nécessaire.
  • Philippe49Philippe49 Membre
    08:28 modifié #14
    Dans ce cas, un seul plist serait suffisant. Je crois que tu t'embêtes pour rien à  vouloir découper, à  moins que le reste de l'appli ne nécessite des ressources très importantes. Et en plus cela risque plus de rendre les transitions moins fluides que le contraire.
  • KyoKyo Membre
    08:28 modifié #15
    Ok, je verrais la réactivité de mon application une fois terminé.

    Pour les tests de performances, tu utilises quoi ? Instruments ?
  • Philippe49Philippe49 Membre
    08:28 modifié #16
    Instruments, oui
Connectez-vous ou Inscrivez-vous pour répondre.