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

Langage Delphi Discussion :

Alternative à un Set Of


Sujet :

Langage Delphi

  1. #41
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Merci ShaiLeTroll. Si je comprends bien l'évolution historique : la structure du Record a donné d'abord l'idée du concept d'Object qui a ensuite donné l'idée du concept de Class et maintenant les Record sont devenu des classes déguisées ... le serpent qui se mord la queue en qq sorte!
    Donc si je ne peux pas utiliser IntegerSets.pas avec Delphi-5, je vais continuer à bidouiller mon Big-Ensemble logé dans un BitMap ... après tout quoi de mieux pour un Set Of de plus de 256 TColor.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  2. #42
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 301
    Points
    11 301
    Billets dans le blog
    6
    Par défaut
    OK, j'ai :
    - lu (rapidement !) l'article mentionné par Laurent dardenne,
    - lu avec attention les remarques de sjrd, mais pas encore regardé sa nouvelle unité,
    - comme Shai Le Troll souvenir du thread cité, mais me rappelle que je n'avais rien compris aux solutions avec arbres...
    - Delphi 5, comme Gilbert Geyer !!!

    j'ai implémenté une classe sommaire avec un arbre (je crois que j'avais surtout envie d'en manipuler un pour la première fois !), mais je n'ai absolument pas testé les performances, et elle n'implémente pas toutes les fonctions d'union etc.
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #43
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Voiçi une variante qui pour l'instant gère l'ajout, la suppression et la recherche d'un élément (de type Integer ou tColor) dans un ensemble logé dans un BitMap à géométrie variable :
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
     
    type tGrosSetOfTColorsOrInteger = Object //Class
               Bmp : tBitMap; R,G,B : byte; Count : Cardinal;
               procedure Create;
               procedure Grow;
               procedure Add(inVal : TColor);
               procedure Delete(inVal : TColor);
               function  Contains(testVal : TColor) : boolean;
               procedure AddSet(inSet : tGrosSetOfTColorsOrInteger); //<- à faire une autre fois Set1 = Set1 + Set2
               procedure Clear;
               procedure Free;
    end;
     
    implementation
     
    {$R *.DFM}
     
    procedure tGrosSetOfTColorsOrInteger.Create;
    begin     Bmp:=tBitMap.create;
              with Bmp do
              begin height:=256; // hauteur constante
                    width:=1;    // largeur initiale
                    pixelFormat:=pf24bit;
                    Canvas.Brush.Color:=RGB(1,1,1);
                    Canvas.FillRect(Rect(0,0,width,height));
              end;
              Count:=0;
    end;
     
    type     tRGBTripleArray =  array [WORD] of tRGBTriple;
             pRGBTripleArray =  ^tRGBTripleArray;
     
    procedure tGrosSetOfTColorsOrInteger.Grow; // Elargissement de l'ensemble
    begin     with Bmp do
              begin width:=width+1;
                    canvas.Pen.Color:=RGB(1,1,1);
                    canvas.MoveTo(width-1,0);
                    canvas.LineTo(width-1,height-1);
                    canvas.refresh;
              end;
    end;
     
    procedure tGrosSetOfTColorsOrInteger.Add(inVal : TColor);
    var       rangee:  pRGBTripleArray; i : integer;
    begin     R:=GetRValue(inVal);
              G:=GetGValue(inVal);
              B:=GetBValue(inVal);
              with bmp do
              begin rangee := Scanline[R]; // on range directement dans la ligne d'indice R
                    i:=-1;
                    repeat inc(i);
                    until (i=width-1)
                       or ((rangee[i].rgbtGreen=1) and (rangee[i].rgbtBlue=1))
                       or ((rangee[i].rgbtGreen=G) and (rangee[i].rgbtBlue=B));
     
                    if (rangee[i].rgbtGreen=G) and (rangee[i].rgbtBlue=B)
                    then EXIT
                    else
                    if (i=width-1) and (rangee[i].rgbtGreen<>1) and (rangee[i].rgbtBlue<>1)
                    then begin Grow; Add(inVal); end
                    else begin inc(Count);
                               rangee[i].rgbtRed:=R; rangee[i].rgbtGreen:=G; rangee[i].rgbtBlue:=B;
                               EXIT;
                    end;
              end;
    end;
     
    procedure tGrosSetOfTColorsOrInteger.Delete(inVal : TColor);
    var       rangee:  pRGBTripleArray; i : integer;
    begin     R:=GetRValue(inVal);
              G:=GetGValue(inVal);
              B:=GetBValue(inVal);
              with bmp do
              begin rangee := Scanline[R]; // on va directement dans la ligne d'indice R
                    i:=0;
                    while (i<width-1) and (rangee[i].rgbtGreen<>G) and (rangee[i].rgbtBlue<>B)
                       do inc(i);
                    if (rangee[i].rgbtGreen=G) and (rangee[i].rgbtBlue=B) then
                    begin rangee[i].rgbtRed:=1; rangee[i].rgbtGreen:=1; rangee[i].rgbtBlue:=1;
                          Dec(Count);
                    end;
              end;
    end;
     
    function  tGrosSetOfTColorsOrInteger.Contains(testVal : TColor) : boolean;
    var       rangee:  pRGBTripleArray; i : integer;
    begin     R:=GetRValue(testVal);
              G:=GetGValue(testVal);
              B:=GetBValue(testVal);
              with bmp do
              begin rangee := Scanline[R]; // on saute directement sur la ligne d'indice R
                    i:=-1;
                    repeat inc(i);
                           if  (rangee[i].rgbtGreen = G)
                           and (rangee[i].rgbtBlue  = B)
                           and (rangee[i].rgbtRed   = R)
                           then begin RESULT:=true; EXIT; end;
                    until (i=width-1);
              end;
              RESULT:=false;
    end;
     
    procedure tGrosSetOfTColorsOrInteger.AddSet(inSet : tGrosSetOfTColorsOrInteger);
    begin     //à faire une autre fois Set1 = Set1 + Set2
    end;
     
    procedure tGrosSetOfTColorsOrInteger.Clear;
    begin     with Bmp do
              begin width:=1;
                    Canvas.Brush.Color:=RGB(1,1,1);
                    Canvas.FillRect(Rect(0,0,width,height));
              end;
              Count:=0;
    end;
     
    procedure tGrosSetOfTColorsOrInteger.Free;
    begin     Bmp.Free; end;
     
    // Utilisation :
     
    var       BigSet : tGrosSetOfTColorsOrInteger;
    procedure TfrmSetOf.bSetBmpClick(Sender: TObject);
    var       i,j,k : integer; Entier : integer;
    begin     memo1.clear;
              BigSet.Create;
              BigSet.Add(clGreen);
              BigSet.Add(clRed);
              BigSet.Add(RGB(44,255,22));
              BigSet.Add(RGB(255,255,22));
              BigSet.Add(clLime);
              BigSet.Add(RGB(255,128,255));
     
              if BigSet.Contains(clRed)  then showMessage('1 : Rouge présent : ok')
                                         else showMessage('1 : Rouge absent');
     
              if BigSet.Contains(clGreen)  then showMessage('1 : Vert présent : ok')
                                           else showMessage('1 : Vert absent');
     
              if BigSet.Contains(clYellow) then showMessage('2 : Jaune présent')
                                           else showMessage('2 : Jaune absent : ok');
              BigSet.Add(clYellow);
              if BigSet.Contains(clYellow) then showMessage('3 : Jaune présent : ok')
                                           else showMessage('3 : Jaune absent');
              BigSet.Add(clYellow);
              if BigSet.Contains(RGB(43,255,22)) then showMessage('4 : 43,255,22 présent')
                                                 else showMessage('4 : 43,255,22 absent : ok');
     
              if BigSet.Contains(RGB(44,255,22)) then showMessage('5 : 44,255,22 présent : ok')
                                                 else showMessage('5 : 44,255,22 absent');
     
              BigSet.Delete(clRed);
              if BigSet.Contains(clRed)  then showMessage('6 : Rouge présent')
                                         else showMessage('6 : Rouge absent : ok');
     
              if BigSet.Contains(clYellow) then showMessage('7 : Jaune présent : ok')
                                           else showMessage('7 : Jaune absent');
     
              for i:=1 to 100 do BigSet.Add(clYellow); // n''en rajoute qu'un seul s'il est absent
     
              if BigSet.Contains(clBlack) then showMessage('8 : Noir absolu  présent ')
                                          else showMessage('8 : Noir absolu absent : ok');
              BigSet.Add(clBlack);
              if BigSet.Contains(clBlack) then showMessage('9 : Noir absolu  présent : ok')
                                          else showMessage('9 : Noir absolu absent');
     
              Entier:=888888;
              BigSet.Add(Entier); //<- Ajout d''un entier pris pour un TColor qui est aussi un integer
              if BigSet.Contains(Entier) then showMessage('10 : Entier présent : ok')
                                          else showMessage('10 : Entier absent');
              BigSet.Delete(Entier);
              if BigSet.Contains(Entier) then showMessage('11 : Entier présent ')
                                          else showMessage('11 : Entier absent : ok');
     
              for i:=0 to 255 do
              for j:=0 to 255 do BigSet.Add(RGB(j,i,128)); 
     
              BigSet.Free;
    end;
     
    procedure TfrmSetOf.bTestVitesseClick(Sender: TObject);
    var       i,j : integer;
    begin     TopChrono:=GetTickCount;
              BigSet.Create;
     
             // A ) Expansion de l'ensemble :
              for i:=0 to 100000 do BigSet.Add(i);
              Trace(ChronoMis); // pour 100000 : 515 ms (Pentium III 1.13 GHz) 
              if BigSet.Contains(100000) then Trace('12 : 100000 présent : ok')
                                         else Trace('12 : 100000 absent');
              if BigSet.Contains(100001) then Trace('13 : 100001 présent')
                                         else Trace('13 : 100001 absent : ok');
     
              // B ) Recherches dans l'ensemble de l'élément absent :
              TopChrono:=GetTickCount;
              for i:=0 to 100000 do if BigSet.Contains(100001) then {} else j:=i;
              Trace(ChronoMis); //pour 100000 : 287 ms
     
              BigSet.Free;
    end;
    // P.S : la procedure "Trace" se contente d'alimenter un memo
    //         et la function ChronoMis renvoie simplement la chaine du delta-T
    A titre indicatif, la constitution d'un Set par ajout de 100000 éléments a pris 515 ms (Pentium III 1.13 GHz) et la recherche dans cet ensemble d'un élément absent 287 ms (oblige à scanner jusqu'à la fin).
    (Delphi-5, Win98, Pentium III 1.13 GHz)

    A+

    EDIT du 26/09/2007 : A propos des tests de vitesse ci-dessus je rectifie le résumé maladroit de mon code ci-dessus : ce n'est pas "la" recherche mais 100000 recherches d'un élément absent qui a pris 287 ms c'est à dire que la recherche d'un seul élément absent prend au maxi 0,00287 ms.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  4. #44
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Oui, les record en BSD sont devenu des classes déguisées ...
    Mais non. Les record ne sont pas des classes déguisées. Une classe est un type référence, qui se transmet et se recopie donc par adresse. Un record est un type valeur, qui se transmet et se recopie par valeur.

    Comme toujours les types références sont alloués sur le tas par un appel à GetMem plus ou moins encapsulé (par exemple dans le constructeur). Les types valeur sont alloués sur la pile (variables locales) ou dans le segment de données (variables globales). Il est possible de définir des constantes d'un type valeur, jamais d'un type référence.

    Cela dit, oui, les méthodes ont été ajoutées aux record avec Delphi 2005, et les class operator avec Delphi 2006. Mais ça n'en fait pas des classes.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  5. #45
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 132
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 132
    Points : 1 418
    Points
    1 418
    Par défaut
    Salut,

    Citation Envoyé par ShaiLeTroll Voir le message
    Oui, les record en BSD sont devenu des classes déguisées ...
    Quid du cas du "packed record" ? (toujours vrai record)

    Yan.


    devYan.

  6. #46
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par devyan Voir le message
    Quid du cas du "packed record" ? (toujours vrai record)
    Le packed record n'est autre qu'un record dont on a supprimé l'alignement des champs : il est moins gros et on en maîtrise la taille, mais il est moins rapide à l'exécution. Mais sinon c'est tout à fait pareil.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  7. #47
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    c'est pour cela que je disais classes déguisées, record qui gère la portée (private, ...), les méthodes (j'ai vu un record ayant des méthodes sur le forum, je peux pas vérifier, je n'ai que D4 à D7 à porte de main) ... ça ressemble fortement à une classe, après comment ça marche, j'espère bien que cela reste un type simple car sinon bonjour la maintenance entre D7 et BSD, mais bon, mes @, ^ et CopyMemory ne doivent plus passer ...

    packed record, est utile pour les echanges de zone mémoire via TCP/IP, cela permet à un programme C (j'ai pas dit ++) et Delphi, de compiler les record de la même façon ... en windows, il me semble que les records sont alignés sur 4 (comme par défaut en delphi 32bits)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #48
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    mais bon, mes @, ^ et CopyMemory ne doivent plus passer ...
    Pourquoi pas ? Bien sûr que si ça fonctionne encore. Heureusement.
    Citation Envoyé par ShaiLeTroll Voir le message
    (comme par défaut en delphi 32bits)
    Les règles d'alignement de Delphi sont très complexes et ne s'arrêtent pas à "simplement 4 octets". Mais je ne les exposerai pas ici, ça serait trop long.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  9. #49
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Les Pointeurs fonctionne pour les Applis 32bits faites avec BSD, mais doivent être interdit si l'on fait du Dot Net ? non ?

    je trouve qu'ajouter tant de chose dans une structure ce n'est pas bon, la structure est souvent utilisé pour une chose précise comme la lecture fichier binaire/typé, ou la transmission de paramètre à une DLL, ..., ensuite, on encapsule la structure dans objet lorsque la manipulation de celle-ci est trop chiante (je pense à l'utilisation de Array of Char au lieu de string qui se lise comme une chaine mais l'affectation étant plus chiante ...)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #50
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Comme la réflexion prend du temps, j'ai un temp de réponse légérement dégradée .
    Citation Envoyé par sjrd
    Mais non. Les record ne sont pas des classes déguisées. Une classe est un type référence, qui se transmet et se recopie donc par adresse. Un record est un type valeur, qui se transmet et se recopie par valeur.
    Cela peut mieux se concevoir si on connait un peu les principes de base de .NET. Ces avancées du langage ont été, à mon avis, implémentées sous Win32 pour faciliter le partage de code Delphi entre Win32 et .NET.

    Et je suis d'accord avec la formulation suivante
    Citation Envoyé par ShaiLeTroll
    les record en BSD sont devenu des classes déguisées ...
    Car, en tenant compte de ma remarque, sous .NET tout est Objet. Comme disait l'autre : Objets avez-vous une classe ...
    Citation Envoyé par sjrd
    Mais ça n'en fait pas des classes.
    J'ajouterais "sous Win32".

    On parle ici du concept et pas de son implémentation au niveau du compilateur. Qui lui réalise un distinguo technique.
    Un record peut être vu, pourquoi pas, comme une classe scellée (Sealed) c'est à dire dans dérivation possible.
    Pour moi ces records avancés répondent à au moins un des principes de la POO à savoir celui de regroupement des données et des traitements.
    Là où on retombe sur nos pieds, enfin en tout cas moi, c'est que les opérateurs,sous Win32, permettent la construction* de nouveaux type.
    * :facilitent la manipulation/simule la construction... Là je ne suis pas certain de la pertinence du 1er terme

    A mon avis la frontiére est ténue entre le concept de type et de classe sous .NET( voir JAVA), cf. "32.ToString", mais clairement identifiée sous Win32.
    Citation Envoyé par Gilbert Geyer
    Si je comprends bien l'évolution historique : la structure du Record a donné d'abord l'idée du concept d'Object
    Oui, enfin c'est plus une évolution des principes de programmation. Le concept était là sous nos yeux, il falllait juste avoir l'idée
    Citation Envoyé par Gilbert Geyer
    l'idée du concept d'Object qui a ensuite donné l'idée du concept de Class
    C'est à peu prés la même chose, les termes définissent 2 choses liées mais distinctes dans le temps et ordonnées. Le concept( une classe) et une ou + de ses réalisations (des objets de cette classe).
    Citation Envoyé par Gilbert Geyer
    le serpent qui se mord la queue en qq sorte!
    Non c'est en serpent qui mue. Il est encore ce qu'il était mais il sera désormais plus que ce qu'il est.

    Quant à ceux qui pensent que les opérateurs c'est que pour les fortiches, bha c'est faux ! Ce n'est que de la grammaire ensuite il faut avoir l'idée d'une implémentation que l'on jugera judicieuse ou élégante. Ici c'est l'idée qui prime, pas l'outil.
    Vous vous en apercevrez une fois pratiqué.

  11. #51
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Les Pointeurs fonctionne pour les Applis 32bits faites avec BSD, mais doivent être interdit si l'on fait du Dot Net ? non ?
    OK, je n'avais pas compris que tu parlais de .NET. En effet en .NET les pointeurs sont interdits.
    Citation Envoyé par ShaiLeTroll Voir le message
    je trouve qu'ajouter tant de chose dans une structure ce n'est pas bon, la structure est souvent utilisé pour une chose précise comme la lecture fichier binaire/typé, ou la transmission de paramètre à une DLL, ..., ensuite, on encapsule la structure dans objet lorsque la manipulation de celle-ci est trop chiante (je pense à l'utilisation de Array of Char au lieu de string qui se lise comme une chaine mais l'affectation étant plus chiante ...)
    C'est un point de vue. A chacun de trouver sa limite. Mais perso, je trouve que dans la situation que nous explorons ici, l'usage de record est parfait.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  12. #52
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Mille excuses : Je ne pensais pas que ma remarque à propos des Record mués en Objects mués à leur tour en Classes allait déclencher un tel débat bien que ce débat soit intéressant.
    Mais comme dans Delphi les Record, les Objects et les Classes continuent à coexister ensemble ceci ressemble à mon point de vue plutôt à une addition de possibilités nées de l'évolution de la réflexion alors que l'image du serpent qui mue évoque chez moi l'idée d'un truc devenu inutile et dont on se débarrasse. Par contre le serpent n'est pas confonté au problème des compatibilités ascendente et descente.

    Pour en revenir au sujet de la gestion des Set Of de plus de 256 éléments je viens d'ajouter un Edit dans mon message d'Hier (25/09/2007) 16h31 a propos de la vitesse d'éxécution du code basé sur le stockage du Set dans un BitMap à géométrie variable consulté via les ScanLine pour rectifier le résumé maladroit de la partie concernée du code joint: ce n'est pas "la" recherche d'un élément, mais les 100000 recherches d'un élément absent du Set des 100000 éléments qui a pris 287 ms c'est à dire que la recherche d'un seul élément absent ou présent prend au maxi 0,00287 ms dans un tel ensemble ... avec ma bécane (Delphi-5, Win98, Pentium III, 1.13 Ghz).

    A mon avis c'est assez encourageant pour continuer à peaufiner cette piste.
    Dommage que IntegerSets.pas de Sjrd ne marche pas sous Delphi-5 j'aurais pu faire des tests de vitesse comparatifs (car inutile de peaufiner mon BitMap s'il y a mieux) ... mais peut-être que Tourlourou qui utilise lui aussi Delphi-5 va nous poster le code de sa classe avec son arbre.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  13. #53
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Gilbert Geyer
    Mille excuses
    Personnellement je ne vois de soucis à cela, à part que la discusion d'origine dérive légérement mais je pense pas que Cl@udius s'en offusque.
    Citation Envoyé par Gilbert Geyer
    ..ceci ressemble à mon point de vue plutôt à une addition de possibilités nées de l'évolution de la réflexion
    C'est exactement ça !
    Dans le même genre, une autre évolution probable sous Win32 avec Tiburon (Delphi 2008), les record générique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     //SPECIFIQUE .NET 2.0 sous Highlander (D2007)
     
     //Record générique, attend un paramètre de type non contraint (de tout type)
     TGenericEnregistrement<T>=Record   
      Data: T;
     End;
     
     //Record générique, attend un paramètre de type contraint 
     //Les contraintes peuvent être couplées. 
    //Ici on attend un paramètre de type classe possédant un constructeur public
     TGenericRecord<C:Class,Constructor>=Record 
      MaClasse : C;
     End;
    Citation Envoyé par Gilbert Geyer
    alors que l'image du serpent qui mue évoque chez moi l'idée d'un truc devenu inutile et dont on se débarrasse.
    Je pensais plus à l'opération de transformation qu'a la peau, qui elle n'est pas devenue inutile mais plutôt inadaptée aux nouvelles conditions, etc.
    Citation Envoyé par sjrd Voir le message
    Les types références sont alloués sur la pile (variables locales)
    Sébastien il y une coquille dans ton énoncé précédent.
    Citation Envoyé par Sjrd
    Une classe est un type référence, qui se transmet et se recopie donc par adresse.
    Un record est un type valeur, qui se transmet et se recopie par valeur.
    Ce qui faut garder à l'esprit c'est que c'est surtout la taille des données qui influencera le choix entre l'une ou l'autre, surtout sous .NET.

    Et Microsoft a fait le choix, d'après un ouvrage de Jeffrey Ritcher , d'utiliser des structures (struct) pour optimiser le code. Imaginez si tous les types était des types références même les types primitifs.

    J'ai une petite question Sébastien, si les classes Win32 avait permis l'usage de la surcharge d'opérateurs aurais-tu utilisé une classe au lieu d'un record pour implémenter TBigValueSet ? Et dans l'affirmative est-ce que cela aurait changé quelque chose à l'usage premier de TBigValueSet ?

  14. #54
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Citation Envoyé par Laurent Dardenne Voir le message
    Personnellement je ne vois de soucis à cela, à part que la discusion d'origine dérive légérement mais je pense pas que Cl@udius s'en offusque.
    En aucun cas offusqué au contraire. Je suis avec intérêt cette discussion qui débat essentiellement autour de l'évolution du langage.

    Citation Envoyé par Laurent Dardenne Voir le message
    J'ai une petite question Sébastien, si les classes Win32 avait permis l'usage de la surcharge d'opérateurs aurais-tu utilisé une classe au lieu d'un record pour implémenter TBigValueSet ? Et dans l'affirmative est-ce que cela aurait changé quelque chose à l'usage premier de TBigValueSet ?
    Classe ou Record, aujourd'hui j'avoue que la nuance m'échappe un peu.
    Ta réponse m'intéresse aussi Seb.

    @+ Claudius

  15. #55
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 301
    Points
    11 301
    Billets dans le blog
    6
    Par défaut
    Voici l'unité, qui n'est ni finalisée, ni optimisée.

    En fait, il manque l'interfaçage avec le TBigValueSet pour gérer l'ensemble, et qq fonctions pour l'union d'ensembles, je pense.

    Pour tests, on peut effectivement vérifier l'inclusion ou non d'un élément, et comparer la vitesse ; j'ai bien peur que ce ne soit pas à l'avantage de l'arbre !!!

    Merci à [G]Gilbert Geyer[/G] s'il veut bien s'en charger (j'ai à peu près comme lui : Delphi-5, Win98, Pentium III, mais 450 Mhz...)
    Fichiers attachés Fichiers attachés
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  16. #56
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Mais comme dans Delphi les Record, les Objects et les Classes continuent à coexister ensemble ceci ressemble à mon point de vue plutôt à une addition de possibilités nées de l'évolution de la réflexion alors que l'image du serpent qui mue évoque chez moi l'idée d'un truc devenu inutile et dont on se débarrasse. Par contre le serpent n'est pas confonté au problème des compatibilités ascendente et descente.
    Pour moi les object ont bien "mués" en class. Les class ont été développées pour remplacer les object. En revanche, les record sont dans une autre "lignée", et n'ont jamais ni été remplacés ni remplacé autre chose.
    Citation Envoyé par Gilbert Geyer Voir le message
    Dommage que IntegerSets.pas de Sjrd ne marche pas sous Delphi-5 j'aurais pu faire des tests de vitesse comparatifs (car inutile de peaufiner mon BitMap s'il y a mieux) ... mais peut-être que Tourlourou qui utilise lui aussi Delphi-5 va nous poster le code de sa classe avec son arbre.
    Je vais t'en préparer une version D5.
    Citation Envoyé par Laurent Dardenne Voir le message
    Sébastien il y une coquille dans ton énoncé précédent.
    Effectivement Corrigé.
    Citation Envoyé par Laurent Dardenne Voir le message
    Ce qui faut garder à l'esprit c'est que c'est surtout la taille des données qui influencera le choix entre l'une ou l'autre, surtout sous .NET.
    Je ne suis pas tout à fait d'accord. Certes en général un record très lourd devrait être évité. Mais le choix entre record ou class est un choix sémantique, pas technique. Une classe n'a pas la même utilisation qu'un record. Mais je serais totalement incapable d'expliquer les différences d'utilisation. C'est une histoire d'habitude et de filling.
    Citation Envoyé par Laurent Dardenne Voir le message
    J'ai une petite question Sébastien, si les classes Win32 avait permis l'usage de la surcharge d'opérateurs aurais-tu utilisé une classe au lieu d'un record pour implémenter TBigValueSet ? Et dans l'affirmative est-ce que cela aurait changé quelque chose à l'usage premier de TBigValueSet ?
    Citation Envoyé par Cl@udius Voir le message
    Classe ou Record, aujourd'hui j'avoue que la nuance m'échappe un peu.
    Ta réponse m'intéresse aussi Seb.
    Comme je l'ai dit, je suis incapable de donner des critères généraux. Mais dans ce cas je n'aurais certainement pas utilisé une classe. Et si les méthodes de record n'avaient pas exister, je n'aurais pas fait une classe non plus, mais bien un record sans méthode, avec des routines associées pour le traiter. C'est dans ce sens que je vais écrire la "version D5" de TBigValueSet.
    En gros ici mon choix vient du fait qu'un ensemble est bel et bien une valeur. Et qu'il est naturel donc d'utiliser un type valeur pour le représenter.
    Citation Envoyé par tourlourou Voir le message
    Voici l'unité, qui n'est ni finalisée, ni optimisée.
    Je regarderai ça
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  17. #57
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par sjrd Voir le message
    Je vais t'en préparer une version D5.
    Ci-jointe. Avec le code de test ci-dessous :
    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
    procedure TestSets;
    var
      BigValues, BigValues2: TBigValueSet;
    begin
      BigValues := BigSetCreate([34, 300]);
      WriteLn(BigValueSetToString(BigValues));
     
      BigValues2 := BigSetUnion(BigValues, BigSetCreate([430, 63, 54]));
      WriteLn(BigValueSetToString(BigValues2));
     
      asm
            MOV     EDX,$00010000
      end;
     
      BigSetInclude(BigValues, 30);
      BigValues2 := BigSetIntersect(BigValues, BigValues2);
      WriteLn(BigValueSetToString(BigValues2));
     
      BigValues := BigSetSubstract(BigValues, BigSetCreate([54, 300]));
      WriteLn(BigValueSetToString(BigValues));
    end;
    Fichiers attachés Fichiers attachés
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  18. #58
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Dites donc, quelle productivité : Merci à Sjrd et à Tourlourou.

    1)
    Sjrd : Pour moi les object ont bien "mués" en class. Les class ont été développées pour remplacer les object. En revanche, les record sont dans une autre "lignée", et n'ont jamais ni été remplacés ni remplacé autre chose.
    ... OK. Par contre je regrette un peu, vu que record signifie enregistrement, que l'on nomme aussi par record une structure qui encapsule des routines comme des object et des class cela devrait, à mon avis, être nommé autrement pour la distinguer sans ambiguité des anciens record qui se contentent d'enregistrer sans actionner quoi que ce soit, en bref un nom distinct pour des choses distinctes.

    2) Tests avec BigSetD7Older.pas et avec CardinalTree.pas : Je les ai téléchargés ils vont m'occuper jusqu'à demain.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  19. #59
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-Bonjour,

    Tiens il ya eu un truc bizarre : Ayant téléchargé CardinalTree.pas et BigSetD7Older.pas il apparaît effectivement chez Tourlourou la mention "1 Affichages" mais il apparaît toujours la mention "0 Affichages" chez Sjrd même après l'avoir téléchargé une deuxième fois par-dessus le premier.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  20. #60
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Premiers résultats de tests :

    1) Avec CardinalTree : En utilisant le code de tests de vitesse suivant :
    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
     
    procedure TfrmSetOf.bTestVitesseCardinalTreeClick(Sender: TObject);
    var       i, N : integer;
    begin     N:=1000; //00;
              Trace('CardinalTree : '+intToStr(N)+' éléments'); // la routine Trace envoie simplement une string dans un memo
     
              TopChrono:=GetTickCount;
              MyTree:=TMyCardBinTree.Create;
     
              for i:=0 to N do MyTree.Add(i);
              Trace('Add : mis : '+ChronoMis);
     
              TopChrono:=GetTickCount;
              for i:=0 to N do if Not MyTree.IsInTheTree(i) then Trace(intToStr(i)+' absent?');
              Trace('IsInTheTree : mis : '+ChronoMis);
     
              MyTree.Free;
     
    end;
    Avec un nombre d'éléments N égal à 100 le chonomètre renvoie 0 millisecondes et avec N = 1000 le test de vitesse est interrompu par le message "feuille 256 déjà initialisée avec la valeur 0" ? Et là je suis sec.

    2) Avec BigSetD7Older: Pour l'instant je n'ai fait qu'un test rudimentaire de fonctionnement avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure TfrmSetOf.bBigSetD7OlderClick(Sender: TObject);
    begin     TestSets;
     
    end;
    ... mais j'ai le message "Erreur E/S 103." ? Et là aussi je suis sec.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

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

Discussions similaires

  1. alterner les couleurs dans un tableau avec xsl
    Par Eithelgul dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 03/05/2015, 23h29
  2. set term ^
    Par tux dans le forum Débuter
    Réponses: 8
    Dernier message: 12/10/2004, 20h42
  3. IB 6.0.1 - Win XP - Character Set
    Par SuperTotor dans le forum InterBase
    Réponses: 4
    Dernier message: 03/06/2003, 20h25
  4. Query data set
    Par Sandra dans le forum JBuilder
    Réponses: 3
    Dernier message: 20/01/2003, 10h08
  5. character set // Nls_lang
    Par fopicht dans le forum Oracle
    Réponses: 2
    Dernier message: 23/05/2002, 12h04

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