Optimiser son code

muqaddarmuqaddar Administrateur
04:11 modifié dans API AppKit #1
Salut,

Bon, je viens de taper ceci dans un tutorial :

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row <br />{<br />       NSString* identifier = [tableColumn identifier];<br />  FoodItem* item = [items objectAtIndex:row];<br />       return [item valueForKey:identifier];<br />}<br /><br />- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row {<br />   NSString* identifier = [tableColumn identifier];<br />  FoodItem* item = [items objectAtIndex:row];<br />       [item takeValue:object forKey:identifier];<br />}<br /><br />- (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn<br />{<br />   NSString* identifier = [tableColumn identifier];<br />  if ([identifier isEqualToString:@&quot;name&quot;]) {<br />             [items sortUsingSelector:@selector(compareName:)];<br />        } else {<br />          [items sortUsingSelector:@selector(comparePrice:)];<br />       }<br /> [table reloadData];<br />}


J'ai beau être bête et discipliné, je remarque que la ligne :

NSString* identifier = [tableColumn identifier];


est écrite dans les 3 méthodes, ce qui me paraà®t répétitif.  :-\

Donc je me demande, si on ne peut pas déclarer cette variable ailleurs, une seule fois, de manière à  ce qu'elle soit reconnue dans toutes les méthodes. Dans ce cas, que vaut-il mieux faire, la déclarer dans le init, dans le header également ?
Ou faut-il la laisser là , pour être dans les conventions de programmation cocoa ?

Voilà , j'espère que cette question n'est pas trop bête.  ??? Mais moi je suis fénéant et écrire 3 fois la même chose ça me fatigue, même un copier/coller.  :P

Réponses

  • 04:11 modifié #2
    Mais en déclarant ta variable ailleurs, cela va juste changer ceci:

    <br />NSString* identifier = [tableColumn identifier];<br />
    


    va devenir

    <br />_MyIdentifier = [tableColumn identifier];<br />
    


    Et tu ne peux affecter la variable une seule fois vu que sa valeur dépend de la colonne en cours. A la rigueur tu peux faire une macro mais y a-t-il beaucoup à  gagner ?  ???
  • nucleusnucleus Membre
    octobre 2004 modifié #3
    dans 1098102111:
    Donc je me demande, si on ne peut pas déclarer cette variable ailleurs, une seule fois, de manière à  ce qu'elle soit reconnue dans toutes les méthodes.

    A moins d'avoir une seule table avec une seule colonne, je vois pas trop où tu vois une optimisation ?

    En la laissant comme variable locale, ca laisse plus de chance au compilateur de faire une optimisation (comme la stocker dans un registre au lieu de la mémoire)


  • octobre 2004 modifié #4
    Et pour la macro, tu peux toujours faire un truc comme ceci:

    <br />#define getColumnId() NSString *identifier =&nbsp; [tableColumn identifier];<br />
    


    il suffira ainsi de faire un getColumnId() pour obtenir ta variable identifier renseignée.

    Mais personnellement, je conserverai la version complète (i.e. sans macro).
  • muqaddarmuqaddar Administrateur
    04:11 modifié #5
    dans 1098104494:

    dans 1098102111:
    Donc je me demande, si on ne peut pas déclarer cette variable ailleurs, une seule fois, de manière à  ce qu'elle soit reconnue dans toutes les méthodes.

    A moins d'avoir une seule table avec une seule colonne, je vois pas trop où tu vois une optimisation ?

    En la laissant comme variable locale, ca laisse plus de chance au compilateur de faire une optimisation (comme la stocker dans un registre au lieu de la mémoire)



    Bein j'ai une seule table à  plusieurs colonnes. Simplement si cette variable est déclarée ailleurs comme dans le init par exemple, les 3 méthodes ne pourraient pas reconnaà®tre quelle colonne est sélectionnée apparemment ?

    Oui, pour la macro, ça a l'air plus compliqué.
  • 04:11 modifié #6
    Initialiser identifier lors de l'init n'est pas possible car tu ne sais pas de quelle colonne tu dois récupérer l'identifiant à  ce moment.

    Pour la méthode setObject et objectValue, tu ne connais la colonne en cours seulement une fois dans la fonction. Idem pour la foncton gérant le click.
  • muqaddarmuqaddar Administrateur
    04:11 modifié #7
    OK deftones_chrix, c'est compris.
    merci.
  • 04:11 modifié #8
    En parlant d'optimisation, n'oubliez pas le "if à  3 pattes" ;)

    if ([identifier isEqualToString:@&quot;name&quot;]) {<br />[items sortUsingSelector:@selector(compareName:)];<br />} else {<br />[items sortUsingSelector:@selector(comparePrice:)];<br />}<br />
    


    peut être sous la forme:
    ([identifier isEqualToString:@&quot;name&quot;])&nbsp; ? [items sortUsingSelector:@selector(compareName:)]&nbsp;  : [items sortUsingSelector:@selector(comparePrice:)];<br />
    

    :sors:
  • Eddy58Eddy58 Membre
    04:11 modifié #9
    En parlant d'optimisation, il y a un excellent outil qui s'appelle Shark, je ne m'en suis jamais servis (pas encore mais ca va venir), mais j'en ai entendu du bien, apparamment c'est d'une grande efficacité. :)
  • muqaddarmuqaddar Administrateur
    04:11 modifié #10
    dans 1098111740:

    En parlant d'optimisation, n'oubliez pas le "if à  3 pattes" ;)

    if ([identifier isEqualToString:@&quot;name&quot;]) {<br />[items sortUsingSelector:@selector(compareName:)];<br />} else {<br />[items sortUsingSelector:@selector(comparePrice:)];<br />}<br />
    


    peut être sous la forme:
    ([identifier isEqualToString:@&quot;name&quot;])&nbsp; ? [items sortUsingSelector:@selector(compareName:)]&nbsp;  : [items sortUsingSelector:@selector(comparePrice:)];<br />
    

    :sors:


    ouais, plus concis, moins long... mais moins clair quand on lit vite non ?
  • nucleusnucleus Membre
    04:11 modifié #11
    dans 1098105113:

    Et pour la macro, tu peux toujours faire un truc comme ceci:

    <br />#define getColumnId() NSString *identifier =  [tableColumn identifier];<br />
    


    il suffira ainsi de faire un getColumnId() pour obtenir ta variable identifier renseignée.

    Mais personnellement, je conserverai la version complète (i.e. sans macro).


    Personnellement je ne fais plus de macros, mais des méthodes "inline"..
    Normalement dans le résultat final c'est pareil, sauf que c'est plus pratique pour la maintenance, le deboggage..
  • 04:11 modifié #12
    dans 1098114675:

    ouais, plus concis, moins long... mais moins clair quand on lit vite non ?


    Est-ce vraiment moins consommateur de ressources que de mette le code en long? Une fois que c'est compilé ça ne doit pas changer grand chose... Par contre la synthaxe (condition)?résultatSiVrai:résultatSiFaux; est intéressante à  l'intérieur même d'un message, ou dans le un calcul. Exemple:
    [(condition)?objet1:objet2 addItem:item];<br /><br />int i = 35 + (condition)?0:10;
    
  • Eddy58Eddy58 Membre
    04:11 modifié #13
    Personnellement, je préfère écrire le code conditionnel entièrement, pour des facilités de relecture et de compréhension. D'une part si on reste de longues périodes sans toucher au code une fois finalisé, et d'autre part pour le déboguage. :)
  • TiffTiff Membre
    04:11 modifié #14
    Dans les exemples de Renaud, qui tiennent sur une seule ligne, le code est très lisible. Je vote pour. C'est tout de même moins lourd que le if else.
    <br />int i;<br />if(condition) i = 35 + 0;<br />else i = 35 + 10;<br />
    

    Et puis, rien n'empêche d'ajouter un petit commentaire.

    Merci à  deftones_chrix et Renaud pour le "Tiff à  trois pattes" que je ne connaissais pas.  8)
  • 04:11 modifié #15
    dans 1098125507:

    Est-ce vraiment moins consommateur de ressources que de mette le code en long?


    Dans l'exemple que je donnai, c'était un peu extrême  ;D
    Perso je m'en sers pour les affectations et les affichages.

    Et concernant les ressources, de nos jours cela ne fait pas gagner grand chose à  l'exécution. Mais à  une époque l'interet était le gain de place (alors que maintenant avec nos mégas en RAM et Go en disque...).

    En effet:
    <br />printf (&quot;nom:%s&#092;n&quot;, (_name == NULL) ? &quot;Non renseigné&quot; : _name);<br />
    

    prends moins de place que:

    <br />if (_name == NULL) {<br />&nbsp; printf (&quot;nom:%s&#092;n&quot;, &quot;Non renseigné&quot; );<br />} else {<br />&nbsp; printf (&quot;nom:%s&#092;n&quot;, _name);<br />}<br /><br />
    



    Nom de Zeus!!!! Je réalise que je commence à  être un "vieux" dévéloppeur  :-\ :o :'(
Connectez-vous ou Inscrivez-vous pour répondre.