ReloadData.. avec des rames

chaps31chaps31 Membre
17:04 modifié dans API AppKit #1
Juste un truc perturbant, j'ai une tableview avec un tableau datasource qui se construit à  partir d'une base postgresql.

Actuellement il y a une 20aine d'enregistrements uniquement pour tester pdt que je code, lorsque je crée un nouvel enregistrement (j'ai fais une interface pour ça dans mon appli) il va s'enregistrer dans la base de donnée et le tableau est mis à  jour ainsi que la tableview avec un reloaddata. Le seul truc c'est que c'est lent...

Le temps de reload est d'environ 3 secondes, une éternité devant l'interface je vous assure, vous avez une idée de l'origine ?

Postgresql qui ne vaut pas mysql ?  >:(
Le mode debug ?  :why?:
Mon codage pas très propre...  :P
«1

Réponses

  • schlumschlum Membre
    17:04 modifié #2
    Postgre est lent... Et puis tu ferais mieux de gérer les données en interne en plus, et de faire une mise à  jour des données en interne dans un thread, ce qui ne ralentirait pas l'interface.
  • chaps31chaps31 Membre
    17:04 modifié #3
    dans 1207678312:

    faire une mise à  jour des données en interne dans un thread


    Heu... c'est à  dire ?  ???  Merci
  • schlumschlum Membre
    17:04 modifié #4
    dans 1207683041:

    dans 1207678312:

    faire une mise à  jour des données en interne dans un thread


    Heu... c'est à  dire ?   ???  Merci


    Ah ben si tu connais pas le multi-threading, c'est sûr tu vas bloquer l'interface à  mort avec ce genre de choses  ???

    http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/Introduction/chapter_1_section_1.html
  • chaps31chaps31 Membre
    avril 2008 modifié #5
    Un peu de lecture, merci, je débute en cocoa avec un assez gros projet mais je suis très persévérant et sans urgence ...

    EDIT : genre un thread qui met ma base de données à  jour pendant qu'un autre thread met à  jour mon tableau (1 ligne) et actualise l'affichage, du coup l'interface bosse rapidement même si en même temps la mise à  jour de la base de donnée est plus lente.
    C'est sûr pour coder moins je reprenais les méthodes déjà  codées : un nouvel enregistrement allait se mettre dans la base puis l'interface rechargeait la base entière, pas vraiment un modèle de rapidité....
    Tout cela vient du fait que je suis amateur et que je m'étais arrêté à  la programmation en PHP non orienté objet... Je découvre tout un nouveau monde et pour ainsi dire, je découvre la programmation ;)
  • AliGatorAliGator Membre, Modérateur
    17:04 modifié #6
    Je dirais plutôt un thread à  part qui met à  jour ta base de données postgre oui, puis qui récupères les nouveaux enregistrements une fois la mise à  jour faite... et une fois qu'il a fait tout ça, donc que la tambouille côté postgre est finie, le thread se termine en signalant au thread/programme principal "ça y est la mise à  jour côté postgre qui traine un peu des pieds est terminé". Et là  alors tu peux faire ton reloadData.

    Ce qui veut dire que pendant que ta base postgre se met à  jour, ton interface n'est pas bloquée et t'auras pas de roue multicolore. C'est seulement                                                                                                                                                                                                      quand la base postgre aura fini son boulot qu'elle va demander à  l'interface de se mettre à  jour, et ça c'est bien plus rapide que tes transactions postgre ;)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
  • schlumschlum Membre
    17:04 modifié #7
    Au fait, le choix de postgre, c'est parce que les données sont sur un serveur distant ?
    Parce que sinon, sqlite est bien plus indiqué pour ce genre de choses  ;)
  • chaps31chaps31 Membre
    17:04 modifié #8
    J'avais éliminé sqlite car il faut que mon appli puisse être multi-poste et j'ai lu que sqlite est monoposte, je me trompe ?
    Si oui, en quoi sqlite est mieux que postgre ?

    Changer de base de donnée ne pose pas de problème, quelques lignes de code à  changer c'est tout.
  • schlumschlum Membre
    17:04 modifié #9
    dans 1207744964:

    J'avais éliminé sqlite car il faut que mon appli puisse être multi-poste et j'ai lu que sqlite est monoposte, je me trompe ?


    C'est pour ça que je demandais si les données étaient sur un serveur distant...
    Mais un doute m'assaille ; qu'appelles-tu multi-poste et mono-poste ??

    Si oui, en quoi sqlite est mieux que postgre ?

    Changer de base de donnée ne pose pas de problème, quelques lignes de code à  changer c'est tout.


    C'est pas une question de mieux ou pas mieux ; c'est une question de base distante ou embedded locale...
    SQLite, il n'y a pas de client/serveur.
  • AliGatorAliGator Membre, Modérateur
    17:04 modifié #10
    Je pense que par "multiposte" il entend en fait "multi-utilisateurs" (ou "multi-connexions simultanées" si tu veux). Pour ne pas que la base ne soit accessible que par un seul client à  la fois.
    Et donc en effet il y a deux choses à  considérer dans le choix du SGBD : le nombre de connexions simultanées possibles, et l'aspect local ou distant.

    Et il me semble si ma mémoire est bonne que sqllite est non seulement local, mais aussi mono-utilisateur (mono-client/mono-connexion)...
  • chaps31chaps31 Membre
    17:04 modifié #11
    Par multiposte j'entends plusieurs ordinateurs (3 ou 4 maxi, mais dans un premier temps 2), avec donc un réseau local et forcément une architecture client / serveur, tous les ordi faisant tourner l'appli mais la BDD ne sera que sur un seul bien sûr.
    Toujours bon , Point de salut avec SQLite ?

    NB : Pour le multiThread ça m'a pas l'air bien compliqué d'après ce que j'ai pu lire, sinon j'ai résolu mon problème en faisant l'effort de coder. En effet il y a 1 valeur de chaque enregistrement qui n'est pas fourni par l'utilisateur mais pas la base : un ID (auto_increment ou bigserial pour postgresql), donc de toute manière pas possible de faire du multithread sur ce coup car il faut que j'attende que l'enregistrement soit fait pour récupérer cet id (utile dans l'interface), mais j'ai recodé, et maintenant je n'extraits plus que l'id nécessaire de la base et j'update le tableau source de la tableview plustôt que de me servir du code déjà  fait qui rapatrie toute la base et recré intégralement le tableau source.
    Maintenant je bute sur un truc stupide : trier mon tableau source après avoir rajouté le nouvel enregistrement :

    [tt]NSdescriptor *descriptor=[[[NSSortdescriptor alloc] initWithKey:@nom  ascending:YES ] autorelease ];
    NSArray *trie=[[NSArray alloc] initWithObjects:descriptor];
    [matable sortedArrayUsingDescriptors:trie];[/tt]

    Ca me fait un magnifique Bug :
    [glow=red,2,300]0 CFRetain
    1 CFArrayCreate[/glow]
    ...

    Une idée ?
  • schlumschlum Membre
    17:04 modifié #12
    dans 1207756235:
    Et il me semble si ma mémoire est bonne que sqllite est non seulement local, mais aussi mono-utilisateur (mono-client/mono-connexion)...


    Suffit d'instaurer un système de lock  :P
    Je l'utilise avec un truc qui a plus de 10 threads, alors...  :o
  • schlumschlum Membre
    17:04 modifié #13
    dans 1207760091:

    Par multiposte j'entends plusieurs ordinateurs (3 ou 4 maxi, mais dans un premier temps 2), avec donc un réseau local et forcément une architecture client / serveur, tous les ordi faisant tourner l'appli mais la BDD ne sera que sur un seul bien sûr.
    Toujours bon , Point de salut avec SQLite ?


    Si on peut toujours utiliser SQLite (via un WebService / SOAP), mais du coup, ça serait beaucoup plus complexe qu'un SGDB utilisant directement un système client / serveur -> postgre est le bon choix.
  • schlumschlum Membre
    17:04 modifié #14
    dans 1207760091:

    NB : Pour le multiThread ça m'a pas l'air bien compliqué d'après ce que j'ai pu lire, sinon j'ai résolu mon problème en faisant l'effort de coder. En effet il y a 1 valeur de chaque enregistrement qui n'est pas fourni par l'utilisateur mais pas la base : un ID (auto_increment ou bigserial pour postgresql), donc de toute manière pas possible de faire du multithread sur ce coup car il faut que j'attende que l'enregistrement soit fait pour récupérer cet id (utile dans l'interface), mais j'ai recodé, et maintenant je n'extraits plus que l'id nécessaire de la base et j'update le tableau source de la tableview plustôt que de me servir du code déjà  fait qui rapatrie toute la base et recré intégralement le tableau source.
    Maintenant je bute sur un truc stupide : trier mon tableau source après avoir rajouté le nouvel enregistrement :

    [tt]NSdescriptor *descriptor=[[[NSSortdescriptor alloc] initWithKey:@nom  ascending:YES ] autorelease ];
    NSArray *trie=[[NSArray alloc] initWithObjects:descriptor];
    [matable sortedArrayUsingDescriptors:trie];[/tt]

    Ca me fait un magnifique Bug :
    [glow=red,2,300]0 CFRetain
    1 CFArrayCreate[/glow]
    ...

    Une idée ?



    Non, le multi-thread c'est pas compliqué du tout... Par contre, quand tu dis que tu ne peux pas l'utiliser, j'ai un gros doute. Tu fais une connexion à  une BDD, donc forcément pendant cette connexion, tu bloques l'interface, ce qui est contre les règles de programmation.

    Quant à  insérer un élément dans un tableau déjà  trié, c'est un algorithme en O(log(n)) par dichotomie ; pourquoi vouloir retrier tout le tableau ??  ???
    Un tri, aussi rapide soit-il est en O(n*log(n)), tu perds un facteur n, c'est énorme !
  • chaps31chaps31 Membre
    17:04 modifié #15
    dans 1207776232:


    Non, le multi-thread c'est pas compliqué du tout... Par contre, quand tu dis que tu ne peux pas l'utiliser, j'ai un gros doute. Tu fais une connexion à  une BDD, donc forcément pendant cette connexion, tu bloques l'interface, ce qui est contre les règles de programmation.


    Je confirme, mais maintenant ça va vite (cf. ci-dessous), l'id fourni par la base de donnée est le champs qui différencie mes enregistrements dans ma programmation j'en ai besoin dans l'interface. C'est vrai que je peux updater mon tableau source sauf pour l'id qui vient après quand la base a fait son boulot mais entre temps si l'utilisateur utilise la fiche... Ca risque d'entrainer un bug...

    dans 1207776232:

    Quant à  insérer un élément dans un tableau déjà  trié, c'est un algorithme en O(log(n)) par dichotomie ; pourquoi vouloir retrier tout le tableau ??  ???
    Un tri, aussi rapide soit-il est en O(n*log(n)), tu perds un facteur n, c'est énorme !


    "c'est un algorithme en O(log(n)) par dichotomie "  hum... si tu le dis  :P  En tout cas c'est sûr c'est stupide je suis d'accord, pour tout te dire  au lancement de l'appli la base est rapatriée intégralement triée (ORDER BY) dans le tableau source, j'ai une méthode qui le fait, donc par petite flemme, lors d'un nouvel enregistrement hop j'appelle la méthode toute faite...  Maintenant que j'ai recodé et ne traite que le nouvel enregistrement c'est instantané mais sans trie, que je n'arrive pas à  faire fonctionner.

    Si j'ai bien compris tu me déconseilles de retrier le tableau, donc il faut que je place le nouvel enregistrement au bon endroit dans le tableau... il faut que j'énumère les lignes jusqu'à  trouver la bonne place alphabétique... C'est plus rapide que les sortdescriptor que je n'arrive pas à  utiliser ?
  • schlumschlum Membre
    avril 2008 modifié #16
    dans 1207814645:

    dans 1207776232:


    Non, le multi-thread c'est pas compliqué du tout... Par contre, quand tu dis que tu ne peux pas l'utiliser, j'ai un gros doute. Tu fais une connexion à  une BDD, donc forcément pendant cette connexion, tu bloques l'interface, ce qui est contre les règles de programmation.


    Je confirme, mais maintenant ça va vite (cf. ci-dessous), l'id fourni par la base de donnée est le champs qui différencie mes enregistrements dans ma programmation j'en ai besoin dans l'interface. C'est vrai que je peux updater mon tableau source sauf pour l'id qui vient après quand la base a fait son boulot mais entre temps si l'utilisateur utilise la fiche... Ca risque d'entrainer un bug...


    Ce qu'on fait dans pareil cas, c'est qu'on met à  jour les données en mémoire avec la base dans un thread ; une fois terminé, le thread appelle :
    [theTableView performSelectorOnMainThread:reloadData withObject:nil waitUntilDone:YES];
    


    Si j'ai bien compris tu me déconseilles de retrier le tableau, donc il faut que je place le nouvel enregistrement au bon endroit dans le tableau... il faut que j'énumère les lignes jusqu'à  trouver la bonne place alphabétique... C'est plus rapide que les sortdescriptor que je n'arrive pas à  utiliser ?


    Non, il faut faire une insertion dichotomique...
    http://fr.wikipedia.org/wiki/Dichotomie

    On ne peut pas programmer sans connaà®tre les concepts principaux d'algorithmique  ???


    Le principe, c'est que pour insérer à  la bonne place un élément dans un tableau ordonné de 1M d'entrées, il faut juste 20 tests.
    Alors que l'insérer à  la fin et re-trier, ça sera de l'ordre de 20M d'opérations.
  • chaps31chaps31 Membre
    avril 2008 modifié #17
    Merci beaucuop de tes infos je vais potasser et mettre en pratique

    EDIT : Je viens de programmer ma première recherche par dichotomie, je dois avouer que c'est impressionant d'efficacité, bon j'ai juste une erreur de 1 ou 2 places faut que je creuse
  • schlumschlum Membre
    17:04 modifié #18
    dans 1207836929:
    EDIT : Je viens de programmer ma première recherche par dichotomie, je dois avouer que c'est impressionant d'efficacité, bon j'ai juste une erreur de 1 ou 2 places faut que je creuse


    Bien sûr que c'est efficace ; c'est de l'ordre du log (on divise par 2 à  chaque test)...  :P
    À chaque fois qu'on double la taille de la liste, on n'ajoute qu'un test !
  • chaps31chaps31 Membre
    17:04 modifié #19
    Tu sais s'il y a des cours d'algorithmique sur le net qui donne des bases comme tu viens de me fournir ?
  • AntilogAntilog Membre
    17:04 modifié #20
    dans 1207836929:

    Merci beaucuop de tes infos je vais potasser et mettre en pratique

    EDIT : Je viens de programmer ma première recherche par dichotomie, je dois avouer que c'est impressionant d'efficacité, bon j'ai juste une erreur de 1 ou 2 places faut que je creuse


    Pourquoi crois-tu qu'un être humain normalement constitué retrouve aussi rapidement une définition dans un dictionnaire de 42.000 mots?
    Grâce à  la dichotomie  <3
  • schlumschlum Membre
    17:04 modifié #21
    dans 1207842571:

    dans 1207836929:

    Merci beaucuop de tes infos je vais potasser et mettre en pratique

    EDIT : Je viens de programmer ma première recherche par dichotomie, je dois avouer que c'est impressionant d'efficacité, bon j'ai juste une erreur de 1 ou 2 places faut que je creuse


    Pourquoi crois-tu qu'un être humain normalement constitué retrouve aussi rapidement une définition dans un dictionnaire de 42.000 mots?
    Grâce à  la dichotomie  <3 <br />


    Ouais, mais une dichotomie à  la fois plus optimisée (parce qu'on a en plus un concept de " guess " ; genre ah, " cacao " ça devrait être à  peu près vers le début) et moins optimisée (souvent, au lieu de faire un test à  la moitié de la partie courante de recherche, on fait 1 test sur chaque dixième à  peu près).
  • schlumschlum Membre
    17:04 modifié #22
    dans 1207842170:

    Tu sais s'il y a des cours d'algorithmique sur le net qui donne des bases comme tu viens de me fournir ?


    Cours complet, je connais pas ; mais en général, il suffit de connaà®tre les termes et de faire des recherches...
    quelques concepts très importants : le backtracking, la récursivité, la dichotomie, les heuristiques...
    Plus évolué : min-max / alpha-bêta, tris rapides (quicksort), théorie des graphes...
    Plus spécialisés : réseaux de neurones, algorithmes génétiques, logique floue...
  • Philippe49Philippe49 Membre
    avril 2008 modifié #23
    Curieux quand même qu'il ne soit pas prévu dans Foundation une classe NSMutableSortedArray où la méthode addObject tiendrait à  jour l'ordre de la table ...
    Cela manque.
  • schlumschlum Membre
    17:04 modifié #24
    dans 1207912703:

    Car il y a fort  à  parier que les NSMutableArray soient des listes chaà®nées ...


    M'étonnerait fort ; les listes chaà®nées ne sont pas faites pour un accès rapide à  un élément particulier...
    À mon avis c'est une implémentation bien plus complexe que ça.
  • Philippe49Philippe49 Membre
    17:04 modifié #25
    Oui, peut-être un mixage entre différents modèles listes chaà®nées , tableaux , hachage ...
    Il reste néammoins que l'implémentation d'une classe NSMutableSortedArray n'est pas une montagne, et que cela manque.
  • Philippe49Philippe49 Membre
    avril 2008 modifié #26
    Un petit essai (optimisé ?) du tri avec NSArray
    Pour une insertion dans un tableau trié de 1 Mo --> 9 dixième de seconde



    % clear;gcc pgm.m -o pgm -framework Cocoa
    % pgm
    AAAA
    AAAB
    AAAC
    AAAD
    AAAE
    2008-04-11 14:03:14.737 pgm[1366:10b] 0.85
    AAAA
    AAAB
    AAAC
    AAAC&
    AAAD
    %


    #import &lt;Foundation/Foundation.h&gt;<br /><br />NSInteger alphabeticSort(id string1, id string2, void *reverse)<br />{<br />&nbsp; &nbsp; if ((NSInteger *)reverse == NO) {<br />&nbsp; &nbsp; &nbsp; &nbsp; return [string2 compare:string1];<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return [string1 compare:string2];<br />}<br /><br /><br />int main(int argc, char**argv){<br />	NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];<br />	NSMutableArray *anArray =[[NSMutableArray alloc] initWithCapacity:1+32*32*32*32];<br />	char i,j,k,l;<br />	for(i=&#39;A&#39;;i&lt;&#39;A&#39;+32;i++) 	for(j=&#39;A&#39;;j&lt;&#39;A&#39;+32;j++)	for(k=&#39;A&#39;;k&lt;&#39;A&#39;+32;k++)	for(l=&#39;A&#39;;l&lt;&#39;A&#39;+32;l++) {<br />		[anArray addObject:[NSString stringWithFormat:@&quot;%c%c%c%c&quot;,i,j,k,l]];<br />	}<br />	for (i=0;i&lt;5;i++) fprintf(stderr,&quot;%s&#092;n&quot;,[[anArray objectAtIndex:i] UTF8String]);<br />	NSDate * date=[NSDate dateWithTimeIntervalSinceNow:0];<br /><br />	NSData *sortedArrayHint = [anArray sortedArrayHint];<br />	[anArray addObject:[NSString stringWithString:@&quot;AAAC&amp;&quot;]];<br />	NSInteger reverse=NO;<br />	NSMutableArray * newArray=[NSMutableArray arrayWithArray:[anArray sortedArrayUsingFunction:alphabeticSort context:&amp;reverse hint:sortedArrayHint]];<br />	[anArray release];<br /><br />	NSLog(@&quot;%lf&quot;,[date timeIntervalSinceNow]);<br />	for (i=0;i&lt;5;i++) fprintf(stderr,&quot;%s&#092;n&quot;,[[newArray objectAtIndex:i] UTF8String]);<br /><br />	[pool release];<br />	return 0;<br />}
    

  • schlumschlum Membre
    17:04 modifié #27
    Un dixième de secondes, ça me paraà®t beaucoup...
    1 Mo ça fait au maximum 1M d'éléments, soit 20 tests  ???
  • Philippe49Philippe49 Membre
    avril 2008 modifié #28
    Y a pas photo, c'est pas du tout au niveau de l'insertion dichotomique.

    On essaye
  • AliGatorAliGator Membre, Modérateur
    avril 2008 modifié #29
    Je vous conseille la lecture de cet article de RidiculousFish : http://ridiculousfish.com/blog/?p=27

    Il a fait un peu l'analyse de tout ça déjà , avec entre autres un graphique surprennant de par le résultat qu'il illustre sur CFArray/NSArray :
    cfarray_results.jpg

    Comparativement aux autres graphes qu'il fait sur les tableaux naà¯fs, les listes chaà®nées, les tables de hachage & co... très intéressante lecture.
  • Philippe49Philippe49 Membre
    avril 2008 modifié #30
    dans 1207917146:

    Y a pas photo, c'est pas du tout au niveau de l'insertion dichotomique.


    Erreur
  • schlumschlum Membre
    17:04 modifié #31
    dans 1207923335:

    dans 1207917146:

    Y a pas photo, c'est pas du tout au niveau de l'insertion dichotomique.


    Ben si, y a une belle photo. La dichotomie sur le même test & matériel prend 0.999895 secondes !!
    Le temps d'accès semble être le plus important dans ce genre de problème.


    Ben écoute, je sais pas trop comment t'as fait tes tests alors  :P

    [Session started at 2008-04-11 17:08:52 +0200.]
    AAAA
    AAAB
    AAAC
    AAAD
    AAAE
    2008-04-11 17:08:57.791 TestArray[54128:10b] filling array : 4.952828 s
    2008-04-11 17:08:57.904 TestArray[54128:10b] sortedArrayHint : 0.112253 s
    2008-04-11 17:08:58.423 TestArray[54128:10b] sortedArrayUsingFunction (with sortedArrayHint) 0.519013 s
    AAAA
    AAAB
    AAAC
    AAAC&
    AAAD
    2008-04-11 17:08:58.829 TestArray[54128:10b] sortedArrayUsingFunction (without sortedArrayHint) 0.406763 s
    AAAA
    AAAB
    AAAC
    AAAC&
    AAAD
    2008-04-11 17:08:58.831 TestArray[54128:10b] dichotomy insert 0.001805 s
    AAAA
    AAAB
    AAAC
    AAAC&
    AAAD

    TestArray has exited with status 0.


    #import &lt;Foundation/Foundation.h&gt;<br /><br />int alphabeticSort(id string1, id string2, void *reverse)<br />{<br />&nbsp; &nbsp; if ((int *)reverse == NO) {<br />&nbsp; &nbsp; &nbsp; &nbsp; return [string2 compare:string1];<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return [string1 compare:string2];<br />}<br /><br /><br />int main(int argc, char**argv){<br />	NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];<br />	struct timeval tv;<br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t0 = tv.tv_sec*1000*1000+tv.tv_usec;<br />	NSMutableArray *anArray =[[NSMutableArray alloc] initWithCapacity:1+32*32*32*32];<br />	char i,j,k,l;<br />	for(i=&#39;A&#39;;i&lt;&#39;A&#39;+32;i++) 	for(j=&#39;A&#39;;j&lt;&#39;A&#39;+32;j++)	for(k=&#39;A&#39;;k&lt;=&#39;A&#39;+32;k++)	for(l=&#39;A&#39;;l&lt;&#39;A&#39;+32;l++) {<br />		[anArray addObject:[NSString stringWithFormat:@&quot;%c%c%c%c&quot;,i,j,k,l]];<br />	}<br />	for (i=0;i&lt;5;i++) fprintf(stderr,&quot;%s&#092;n&quot;,[[anArray objectAtIndex:i] UTF8String]);<br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t1 = tv.tv_sec*1000*1000+tv.tv_usec;<br />	NSLog(@&quot;filling array : %f s&quot;,(t1-t0)/(1000.*1000));<br />	NSData *sortedArrayHint = [anArray sortedArrayHint];<br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t2 = tv.tv_sec*1000*1000+tv.tv_usec;<br />	NSLog(@&quot;sortedArrayHint : %f s&quot;,(t2-t1)/(1000.*1000));<br />	[anArray addObject:[NSString stringWithString:@&quot;AAAC&amp;&quot;]];<br />	int reverse=NO;<br />	NSArray *newArray = [anArray sortedArrayUsingFunction:alphabeticSort context:&amp;reverse hint:sortedArrayHint];<br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t3 = tv.tv_sec*1000*1000+tv.tv_usec;<br />	NSLog(@&quot;sortedArrayUsingFunction (with sortedArrayHint) %f s&quot;,(t3-t2)/(1000.*1000));<br />	for (i=0;i&lt;5;i++) fprintf(stderr,&quot;%s&#092;n&quot;,[[newArray objectAtIndex:i] UTF8String]);<br />	NSArray *newArray2 = [anArray sortedArrayUsingFunction:alphabeticSort context:&amp;reverse hint:nil];<br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t4 = tv.tv_sec*1000*1000+tv.tv_usec;<br />	NSLog(@&quot;sortedArrayUsingFunction (without sortedArrayHint) %f s&quot;,(t4-t3)/(1000.*1000));<br />	for (i=0;i&lt;5;i++) fprintf(stderr,&quot;%s&#092;n&quot;,[[newArray2 objectAtIndex:i] UTF8String]);<br />	[anArray removeLastObject];<br />	int min = 0;<br />	int max = [anArray count]-1;<br />	int curr;<br />	int r;<br />	while(max-min&gt;1) {<br />		curr = (min+max)/2;<br />		r = alphabeticSort([anArray objectAtIndex:curr],@&quot;AAAC&amp;&quot;,&amp;reverse);<br />		if(r&lt;0)<br />			min = curr;<br />		else if(r&gt;0)<br />			max = curr;<br />		else<br />			min = max = curr;<br />	}<br />	[anArray insertObject:[NSString stringWithString:@&quot;AAAC&amp;&quot;]<br />				&nbsp; atIndex:max];<br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t5 = tv.tv_sec*1000*1000+tv.tv_usec;<br />	NSLog(@&quot;dichotomy insert %f s&quot;,(t5-t4)/(1000.*1000));<br />	for (i=0;i&lt;5;i++) fprintf(stderr,&quot;%s&#092;n&quot;,[[anArray objectAtIndex:i] UTF8String]);<br />	[anArray release];<br />	[pool release];<br />	return 0;<br />}
    


    (tu m'excuseras, j'ai re-pompé ton code en grande partie...)
Connectez-vous ou Inscrivez-vous pour répondre.