4

J'ai un graphique d'objet en Objective-C sur la plate-forme iPhone que je souhaite persister à clignoter lors de la fermeture de l'application. Le graphique a environ 100k-200k objets et contient de nombreuses boucles (par conception). Je dois être capable de lire/écrire ce graphique le plus rapidement possible. Jusqu'à présent, j'ai essayé d'utiliser NSCoder. Cela ne se limite pas aux boucles, mais prend aussi un certain âge et une quantité importante de mémoire pour conserver le graphe - peut-être parce qu'un document XML est utilisé sous les couvertures. J'ai également utilisé une base de données SQLite, mais parcourir autant de lignes prend aussi beaucoup de temps. J'ai envisagé d'utiliser Core-Data, mais je crains de subir les mêmes problèmes que SQLite ou NSCoder car je pense que les banques de données de base fonctionneront de la même manière.Façon optimale de persister un graphique d'objet à clignoter sur l'iPhone

Alors, y a-t-il un autre moyen de gérer la persistance de ce graphe d'objets de façon légère - idéalement, j'aimerais quelque chose comme la sérialisation de Java? J'ai pensé essayer Tokyo Cabinet ou écrire la mémoire occupée par le tas de structures C sur le disque - mais cela va être beaucoup de travail de réécriture.

Répondre

1

Je recommanderais de réécrire comme c structs. Je sais que ce sera une douleur, mais non seulement il sera rapide d'écrire sur le disque, mais devrait fonctionner beaucoup mieux. Avant que quelqu'un ne se fâche, je ne dis pas que les gens devraient toujours utiliser des structures, mais il y a des situations où c'est réellement meilleur pour la performance. Surtout si vous pré-allouer votre mémoire dans des blocs contigus de 20k à la fois (avec des pointeurs dans le bloc), plutôt que de créer/allouer beaucoup de petits morceaux dans une boucle répétée.

Par exemple, si votre boucle alloue continuellement des objets, cela va ralentir. Si vous avez préalloué 1000 structs et que vous avez juste un tableau de pointeurs (ou un seul pointeur), alors c'est une magnitude beaucoup plus grande.

(j'ai eu des situations où même mon mac de bureau était trop lent et n'a pas assez de mémoire pour faire face à ces millions d'objets créés dans une rangée)

+0

Tant que vous ne transférez pas vos fichiers de vidage d'un ordinateur à l'autre, un vidage brut de la mémoire se passera bien. Si vous essayez de partager le fichier entre différentes machines, vous aurez des problèmes de "byte order". C'est nettement mieux dans certaines circonstances. – corydoras

1

Au lieu de rouler vos propres, je très recommandons de jeter un autre coup d'œil aux données de base. Core Data a été conçu à partir de persisting object graphs. Une archive basée sur NSCoder, comme celle que vous décrivez, nécessite que le graphe d'objet entier soit en mémoire et que toutes les écritures soient atomiques. Core Data apporte des objets dans et hors de la mémoire selon les besoins, et ne peut écrire que la partie de votre graphique qui a été modifiée sur le disque (via SQLite).

Si vous lisez le Core Data Programming Guide ou leur tutorial guide, vous pouvez voir qu'ils ont beaucoup réfléchi à l'optimisation des performances. Si vous suivez les recommandations d'Apple (ce qui peut sembler contre-intuitif, comme leur suggestion de dénormaliser vos structures de données à certains moments), vous pouvez extraire beaucoup plus de performance de votre modèle de données que vous ne le pensez. J'ai vu des benchmarks où Core Data bat facilement SQLite pour l'accès aux données dans les bases de données de la taille que vous regardez.

Sur l'iPhone, vous bénéficiez également de certains avantages en termes de mémoire lors de l'utilisation du contrôle de la taille du lot des extractions et d'une classe d'assistance très intéressante dans NSFetchedResultsController.

Cela ne devrait pas prendre autant de temps pour construire une implémentation de données de base de preuve de principe de votre graphique pour le comparer à vos méthodes de stockage de données existantes.

+0

Cela ne rencontrera jamais les mêmes performances qu'un chargement/déchargement en masse de mémoire si c'est tout ce que l'utilisateur essaie d'accomplir. – corydoras

+1

Mais ce n'est pas tout ce qu'ils essaient de faire. Ils essaient de gérer un graphe d'objets complexe, y compris la sérialisation et la désérialisation, un cas pour lequel Core Data est parfaitement adapté. En outre, si cela est fait correctement en utilisant les données de base, l'ensemble du graphique de l'élément 100k-200k ne devrait pas être chargé en mémoire à la fois, un avantage énorme pour un appareil à mémoire limitée comme l'iPhone. –

Questions connexes