Un trie rapide siouplait !

janvier 2008 modifié dans API AppKit #1
Bonsoir,

Je m'explique :D
Mon application (http://www.eagle-of-liberty.com/totaltunescontrol/) qui permet de contrôler iTunes, permet aussi le track listing de l'album.
Cependant. Je n'ai trouvé aucun autre moyen que d'énumérer toute la library puis de comparer à  chaque fois l'album en cours par celui du track énuméré.

La structure d'un track comprend toute sorte d'infos. Ainsi :
NSString* album = [track album];

Je voudrais donc savoir s'il n'y a pas un moyen plus RAPIDE.

<br />while(track=[enumerator nextObject])<br />&nbsp; &nbsp; &nbsp;if([[track album] isEqualTo:currentAlbum])<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Ajout de &quot;Track&quot; dans ma NSArray<br />

C'est du lourd. surtout pour une grosse library de 10Go de musique.

En voyant la rapidité de la recherche d'une chanson sur iTunes, et en voyant la rapidité de récupération des tracks de l'album sur un iPod Touch/iPhone... je me dit merde, j'ai loupé quelque chose ?

Je suis partant pour en apprendre plus sur le trie  <3 <br />
À noter que ça prend 3-4 secondes sur mon iMac 1.83Ghz Intel Core Duo, mais sur un Macmini ou PPC ça devient plus lent et y'en a pour qui ça peut prendre 1 minute..

Réponses

  • Philippe49Philippe49 Membre
    janvier 2008 modifié #2
    Pour comparer des C-string, tu as en C radixsort et sradixsort, qui dans ce cas doivent être meilleures que qsort.


    et pour atteindre rapidement un élément d'un tableau trié, la recherche dichotomique.
  • 19:05 modifié #3
    dans 1199494652:

    Pour comparer des C-string, tu as en C radixsort et sradixsort, qui dans ce cas doivent être meilleures que qsort.


    En fait, le problème c'est que je dois récupérer [track album]. Et je SAIS qu'il y a un moyen d'énumérer plus rapidement sans devoir faire if([track album]....). Sauf que je n'ai jamais su comment.
  • AliGatorAliGator Membre, Modérateur
    19:05 modifié #4
    AppleScript?
  • Philippe49Philippe49 Membre
    janvier 2008 modifié #5
    Il semble que ton objet track parcourt un NSArray.
    NSArray propose une méthode pour obtenir un objet dans une NSArray  [allTracks indexOfObject:myTrack]
    l'optimisation n'est peut-être pas terrible : à  essayer.

    Sinon on peut peut-être utiliser NSSet, dont voici un élémet de la doc
    You can use sets as an alternative to arrays when the order of elements isn't important and performance in testing whether an object is contained in the set is a consideration. While arrays are ordered, testing them for membership is slower than testing sets.
  • schlumschlum Membre
    19:05 modifié #6
    Ce n'est pas un tri qu'il te faut mais une table de hashage...

    Si l'objet "Track" est à  toi, tu peux lui définir la méthode :
    - (unsigned)hash
    

    En fonction de l'album

    ça permettra de faire des recherches très rapides sur des albums.
  • 19:05 modifié #7
    Ca semble bien compliqué tout ca... Pourquoi ne pas récupérer le tableau des pistes depuis une AppleScript ? Bon, d'accord c'est lent pour la bibliothèque principale mais sinon ca devrait aller ? Non ? Bon, ok.
  • Philippe49Philippe49 Membre
    19:05 modifié #8
    Mais NSSet le fait pour vous : Pour pouvoir détecter si un objet appartient à  un ensemble (non ordonné à  priori), il faut que par derrière, l'architecture utilisée soit fichtrement bien ordonnée !!

  • 19:05 modifié #9
    La solution à  ce problème est d'indexer la liste de pistes. Bon, l'indexation est une matière en soi, mais dans le cas présent il y a une solution facile à  mettre en oe“uvre.

    Je suppose que tu lis [tt]iTunes Music Library.xml[/tt] puis tu énumère la liste des pistes pour obtenir des objets "Track". Donc ce que je ferais sur cette base, pendant que tu énumères cette liste tu rajoutes quelques instructions pour créer en parallèle de ton tableau principal un NSDictionary qui contient des NSArray de NSTrack avec comme clé l'album. Comme ça il devient inutile de parcourir toute la collection vu que le travail aura déjà  été prédigéré.

    Mais le mieux est encore d'utiliser des librairies comme CoreData qui servent justement à  faire cela (quoi que, vu le contexte ce n'est peut-être pas l'idéal).
  • 19:05 modifié #10
    Je vais encore apporter des informations.
    Plus précisément j'utilise eyeTunes (un framework). Il y a ETPlaylist pour chaque listes de lecture (sachant que Mix de soirée, Musique, et tout ça sont aussi des ETPlaylist).

    Dans ETPlaylist, je peux récupérer "tracks", qui me retourne une NSArray.
    Donc évidemment je choisi la liste de lecture "musique" qui contient toutes les musiques.
    Pourquoi je ne fait pas de pré-chargement avec un pré-triage :
    1- ça peut-être aussi long pour des grosses libraries
    2- L'utilisateur utilise mon logiciel tout le temps, donc si il rajoute des listes de lecture ou des musiques, il doit recharger le tout. Encore un truc chiant. Pour l'instant le trie des playlists est plutôt rapide donc ça va.

    Un ETTrack est composé de toutes les infos sur un track.

    Le framework utilise l'applescript et appel à  chaque fois iTunes pour récupérer toutes ces informations.

    Donc Renaud, ta méthode est bien entendu très claire est c'est une solution, sauf que ça m'oblige à  tout de même faire un gros trie dès le début, et à  chaque fois que l'utilisateur choisi "Reload playlists".

    Je regarderai du côté de NSSet pour voir ce que ça donne exactement car pour l'instant je ne connais pas. Merci de votre aide.

Connectez-vous ou Inscrivez-vous pour répondre.