IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

[C#]Est-ce que le compilateur jit optimise?


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Par défaut [C#]Est-ce que le compilateur jit optimise?
    Bonjour,

    juste une simple question sur les accès aux tableaux.

    Est-ce que lorsque j'écris ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for (int i = 0; i < len; i++)
    {
        if (data[i] > 255 || data[i] < 0)
                Invalide(data[i]);
        check += trameInterface[i + 3] = data[i];
    }
    Le compilateur voit-il que data[i] est le même dans toute la boucle, ou refait-il un accès au tableau à chaque apparition?

    Dit autrement, dois-je explicitement écrire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for (int i = 0 ; i < len; i++)
    {
        var dat = data[i];
        if (dat > 255 || dat < 0)
            Invalide(dat);
        check += trameInterface [i+3] = dat;
    }
    ?

    Merci d'avance,
    Claude

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 99
    Par défaut
    Je ne crois pas qu'il puisse le faire si data n'est pas de type intégré.

    Imagine...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int this[int index]
    {
    get{ _calls++; return(bla); }
    }
    sinon OUI

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    int a = data[i];
    
         0000001e  cmp         edx,edi 
         00000020  jae         00000070 
         00000022  mov         eax,dword ptr [esi+edx*4+8]
    
    
    if (data[i] > 255 || data[i] < 0)
    
         00000026  cmp         eax,0FFh 
         0000002b  jg          00000031 
         0000002d  test        eax,eax 
         0000002f  jge         00000033 
    
    EDIT : Le lien n'était pas bon, il traite d'une autre optimisation + ajout code.

  3. #3
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Est-ce que le compilateur jit optimise?
    En toute logique, je dirai qu'il n'y a pas d'optimisation du code MSIL par le compilateur jit (à l'exception de la transformation des instructions allongées en instructions abrégées, par exemple, br en br.s).

    Par contre, l'optimisation se fait lors de la compilation du code C# vers MSIL quand on fait un build du projet.

  4. #4
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Par défaut
    Par contre, l'optimisation se fait lors de la compilation du code C# vers MSIL quand on fait un build du projet.
    Ben justement, j'ai vérifié avec reflector et dans le MSIL on retrouve toutes les accès indexés au tableau, donc pas trace d'optimisation à ce niveau.

    sinon OUI
    Ok, merci (ce sont des tableaux de int).

    Je ne crois pas qu'il puisse le faire si data n'est pas de type intégré.
    Alors par précaution je vais quand même conserver mon ancienne technique d'une variable intermédiaire, afin de rester cohérent.

    mov eax,dword ptr [esi+edx*4+8]
    Les langages d'assemblage de ces petites bêtes deviennent vraiment puissants, j'apprécie cet adressage à sa juste valeur

    Merci à vous deux
    Claude

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 99
    Par défaut
    Citation Envoyé par Graffito Voir le message
    En toute logique, je dirai qu'il n'y a pas d'optimisation du code MSIL par le compilateur jit (à l'exception de la transformation des instructions allongées en instructions abrégées, par exemple, br en br.s).

    Par contre, l'optimisation se fait lors de la compilation du code C# vers MSIL quand on fait un build du projet.
    Pas du tout d'accord et je le prouve.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int[] data = new int[256];
     
    int total = 0;
    for (int i = 0; i < 255; i++)
    {
         int a = data[i];
     
         if (data[i] > 255 || data[i] < 0)
              total = data[i];
    }
    IL
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
     IL_0000:  ldc.i4     0x100
      IL_0005:  newarr     [mscorlib]System.Int32
      IL_000a:  stloc.0 // ARRAY = loc 0
     
      IL_000b:  ldc.i4.0
      IL_000c:  stloc.1 // TOTAL = loc 1
     
      IL_000d:  ldc.i4.0
      IL_000e:  stloc.2 // I = loc 2
     
      IL_000f:  br.s       IL_002d // goto debut de boucle 
     
      IL_0011:  ldloc.0 // data
      IL_0012:  ldloc.2 // [i]
      IL_0013:  ldelem.i4 // push data[i]
      IL_0014:  pop       // a = data[i] (NE SERT A RIEN)
     
      IL_0015:  ldloc.0 // data
      IL_0016:  ldloc.2 // [i]
      IL_0017:  ldelem.i4 // push data[i]
      IL_0018:  ldc.i4     0xff // push 255
      IL_001d:  bgt.s      IL_0025 // if data[i] > 255 goto IL_0025
     
      IL_001f:  ldloc.0 // data
      IL_0020:  ldloc.2 // [i]
      IL_0021:  ldelem.i4 // push data[i]
      IL_0022:  ldc.i4.0 //  0
      IL_0023:  bge.s      IL_0029 // if data[i] >= 0 goto IL_0029
     
      IL_0025:  ldloc.0 // data
      IL_0026:  ldloc.2 // i
      IL_0027:  ldelem.i4 // push data[i]
      IL_0028:  stloc.1 // total 
     
      IL_0029:  ldloc.2 // i
      IL_002a:  ldc.i4.1 // 1
      IL_002b:  add      //  i + 1
      IL_002c:  stloc.2   // i = i +1
      IL_002d:  ldloc.2 // i
      IL_002e:  ldc.i4     0xff // push 255
      IL_0033:  blt.s      IL_0011 // if i < 255 goto IL_0011
    ...
    ASM (jitté)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    ...
    00000006  mov         edx,100h 
    0000000b  mov         ecx,7413A0BEh 
    00000010  call        FFCF0C90 // new array[256]
    00000015  mov         esi,eax // esi = data
     
    00000017  xor         ebx,ebx // ebx = total = 0
    00000019  xor         edx,edx // edx = i = 0
    0000001b  mov         edi,dword ptr [esi+4] // [edi+4] = 255 
     
    0000001e  cmp         edx,edi // compare i et 255
    00000020  jae         00000070 // si i >= goto 70
    00000022  mov         eax,dword ptr [esi+edx*4+8] // eax = data[i]
     
    00000026  cmp         eax,0FFh // if i > 255
    0000002b  jg          00000031  // goto 31
    0000002d  test        eax,eax // eax and eax
    0000002f  jge         00000033 // if eax >= 0 goto 33
     
    00000031  mov         ebx,eax // ebx = total = data[i]               
    00000033  inc         edx // i++
    00000034  cmp         edx,0FFh // compare eax et 255
    0000003a  jl          0000001E // si < alors goto 1e
    Conclusion le JIT a très nettement optimisé l'IL, CQFD.
    (et c'est tant mieux sinon il y aurait une préférence pour le langage .NET selon le compilateur alors que là, le JIT les mets tous à niveaux).

    EDIT : j'oubliais, pour ma part je ne répéte jamais 2 fois une expression composé. data[i], data[1], data[j] dans le stress tu peux le lire 100 fois et ne pas te rendre compte tu as mis j ou 1 ou l au n'importe quoi d'autre au lieu de i.

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Par défaut
    Merci pour ce complément d'infos

    EDIT : j'oubliais, pour ma part je ne répéte jamais 2 fois une expression composé. data[i], data[1], data[j] dans le stress tu peux le lire 100 fois et ne pas te rendre compte tu as mis j ou 1 ou l au n'importe quoi d'autre au lieu de i.
    Oui, c'est clair que j'ai donné volontairement un exemple un peu extrême (dans ces cas-là j'utilise aussi systématiquement une variable.

    Par contre, je rencontre souvent des cas du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (tableau[1] == xxxxxx)
          tableau[1].methode();
    if (tableau[2] = yyyyyy)
        autrechose(tableau[2]);
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (tableau[i]>= 0 && tableau[i] <= 0xFF)
      {
           plusbesoindetableau[i]
      }
    et dans ces cas-là c'était un peu lourd d'initialiser une variable à chaque fois, d'où ma question

    De toutes façons maintenant, j'ai ma réponse, encore merci

    Claude

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Est-ce que déclarer un import quand on en a besoin est une optimisation ?
    Par clavier12AZQSWX dans le forum Général Python
    Réponses: 14
    Dernier message: 10/07/2012, 20h09
  2. Qu'est ce que c'est : Le GateA20 ?
    Par le mage tophinus dans le forum x86 16-bits
    Réponses: 5
    Dernier message: 24/02/2003, 15h09
  3. Qu'est ce que le cache ?
    Par irrou dans le forum Assembleur
    Réponses: 4
    Dernier message: 24/11/2002, 23h28
  4. Qu'est-ce que c'est que Nessus, ça fait quoi exactement ?
    Par PeterT dans le forum Développement
    Réponses: 3
    Dernier message: 24/07/2002, 11h23
  5. Réponses: 3
    Dernier message: 19/07/2002, 15h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo