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 :

De l'initialisation des tableaux dynamiques de Record


Sujet :

Langage Delphi

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 17
    Points : 9
    Points
    9
    Par défaut De l'initialisation des tableaux dynamiques de Record
    Yep,

    après mon avancée en territoire 3D, j'ai voulu aller plus vite... Alors j'ai eu l'idée d'implémenter le Z-Buffer... Ce tableau dynamique à deux dimensions de Record est l'image 3D de chaque point d'un TBitmap.

    Sa déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
      TZPoint = record
                      _3D:TD3Point;
                      _color:TColor;
                      _colorized:TColor;
                      _object:TObject;
                end;
     
        _buffer:array of array of TZPoint;
    Son initialisation :
    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
     
    procedure TZCanvas.DoClear(const _width:Integer; const _height:Integer);
     
    begin
         System.SetLength(self._buffer, 0);
     
         if Assigned(self._bitmap)
            then begin
                      self._bitmap.Height := _height;
                      self._bitmap.Width  := _width;
     
                      System.SetLength(self._buffer, _height, _width);
     
                      for _y := Low(self._buffer) to High(self._buffer)
                          do begin
                                  for _x := Low(self._buffer[0]) to High(self._buffer[0])
                                      do with self._buffer[_y][_x]
                                              do begin
                                                      _3D.X := NaN;
                                                      _3D.Y := NaN;
                                                      _3D.Z := NaN;
     
                                                      _color := clNone;
                                                      _colorized := clNone;
     
                                                      _object := nil;
                                                 end;
                             end;
             end;
    end;
    C'est très efficace pour gérer les parties cachées (algorythme du Z-Buffer), mais c'est d'une lenteur quand à l'initialisation... !

    Une idée... ?

  2. #2
    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
    Tu pourrais au minimum définir une constante pour ton record répétitif : l'initialisation d'un record se ferait au moins avec un unique Move.

    Aussi, ton style d'écriture de code est... Etrange Pas facile de te lire. En autres choses : pourquoi tous des _, et pourquoi répéter le self. ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    const
      EmptyZPoint: TZPoint = (
        _3D: (X: NaN; Y: NaN; Z: NaN);
        _color: clNone; _colorized: clNone; _object: nil
      );
     
    for I := Low(_buffer) to High(_buffer) do
      for J := Low(_buffer[i]) to High(_buffer[i]) do
        _buffer[i][J] := EmptyZPoint;
    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.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 17
    Points : 9
    Points
    9
    Par défaut
    Oui !

    effectivement !

    Je ne sais pas pourquoi je n'y avait pas pensé !

    sûrement très absorbé par l'implémentation sur un TCanvas...

    >>> les underscores (_) : pour bien différencier fonctions, properties et variables !

    >>> le self : je viens du C++, et c'est une vieille habitude. D'autres part le code est un portage d'une librarie à moi, d'une époque et d'un environnement qui ne connait pas la VCL, ni ses noms de variables, alors je différencie par self systématiquement !

    Sinon, je viens d'intégrer, et ça accélère les choses, mais c'est encore assez lent !

    Impossible d'initialiser une ligne entière par un fillchar ou un move...?

    Je pensais à un minitableau dynamique qui m'indiquerait l'état de chaque point .... à la manière d'un index...

  4. #4
    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
    Bah tu peux encore linéariser les boucles, mais après je crois bien que c'est tout. A part une optimisation assembleur, si c'est vraiment la partie critique de ton code.
    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
    type
      PZPoint = ^TZPoint;
    var
      Count, I: Integer;
      ZPoint: PZPoint;
    begin
      SetLength(_buffer, _width, _height);
      Count := _width*_height;
     
      ZPoint := @_buffer[0][0];
      for I := 0 to Count-1 do
      begin
        ZPoint^ := EmptyZPoint;
        Inc(ZPoint); // passe au suivant
      end;
    end;
    Mais non un FillChar ou Move n'est pas possible car NaN et clNone ne sont pas des 0 binaires

    Si c'est vraiment toujours trop lent, je te fais une version ASM (à moins que tu ne saches le faire toi-même )
    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. #5
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    il peut aussi creer un tableau de record d'une dimmension qu'il initialise
    en ensuite inittialisé sont tableau a deux dimention avec le le tableau a 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    const
      EmptyZPoint: TZPoint = (
        _3D: (X: NaN; Y: NaN; Z: NaN);
        _color: clNone; _colorized: clNone; _object: nil
      );
     
    setlength(_tmp,width);
    for J := Low(_tmp) to High(_tmp) do
        _tmp[J] := EmptyZPoint;
     
    setlength(_buffer,heigth,width);
    for I := Low(_buffer) to High(_buffer) do
       _buffer[I] := _tmp;
    je n'ai pas teste mais le principe et là

    @+ Phil
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  6. #6
    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
    Ah effectivement c'est pas idiot, ça J'y avais même pas pensé du tout
    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. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 17
    Points : 9
    Points
    9
    Par défaut
    Le truc de linéarisation m'avait échappé, trop content de stocker 3 dimensions dans 2 dimensions...

    Alors caser les 2 dimensions dans une seule...

    Bah j'y étais quand je savais ma géométrie, mais j'ai un peu oublié depuis....

    Ceci dit, la routine assembleur m'interresse...

    * pas sûr que l'affectation des record d'array soient réèllement pascalissimes... je teste....

    Si ça vous interresse, j'ai maintenant un TZCanvas.... héhé....

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 17
    Points : 9
    Points
    9
    Par défaut
    bon ça passe pas le coup des pointeurs.

    Je pensais à l'option d'optimisation Record field alignment $A....mais j'aime pas modifier les options par défaut du compilo....

  9. #9
    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 metanil Voir le message
    bon ça passe pas le coup des pointeurs.
    Oui c'est vrai, désolé, je réfléchissais avec des tableaux statiques. Bon je vais adapter la solution d'anapurna pour tableau dynamique.

    Quel est l'ordre de grandeur de Width et Height ? Et les X, Y, Z sont-il Single/Double/Extended ?
    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.

  10. #10
    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
    Bon avec ce code j'obtiens des résultats très bons (~100 ms) avec Width = Height = 1000. Avec 5000 ce n'est plus le temps CPU qui est à la traîne mais l'utilisation du fichier d'échange mémoire (le swap, quoi ). Donc à mon avis on peut difficilement faire mieux
    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
    unit SomeTest;
     
    interface
     
    uses
      Windows, Graphics, Math;
     
    procedure DoSomeTest;
     
    implementation
     
    type
      TD3Point = record
        X, Y, Z: Double;
      end;
     
      PZPoint = ^TZPoint;
      TZPoint = record
        _3D: TD3Point;
        _color: TColor;
        _colorized: TColor;
        _object: TObject;
      end;
     
    type
      TPointRow = array of TZPoint;
      TBuffer = array of TPointRow;
     
    const
      EmptyZPoint: TZPoint = (
        _3D: (X: NaN; Y: NaN; Z: NaN);
        _color: clNone; _colorized: clNone; _object: nil
      );
     
    procedure ClearABuffer(Width, Height: Integer);
    var
      Buffer: TBuffer;
      FirstRow: TPointRow;
      I, RowSize: Integer;
    begin
      SetLength(Buffer, Height, Width);
      RowSize := Width*SizeOf(TZPoint);
     
      // Fill the first row
      FirstRow := Buffer[0];
      for I := 0 to Width-1 do
        FirstRow[I] := EmptyZPoint;
     
      // Copy first row to other rows
      for I := 1 to Height-1 do
        Move(FirstRow[0], Buffer[I][0], RowSize);
    end;
     
    procedure DoSomeTest;
    var
      BeginTime, EndTime: Integer;
    begin
      BeginTime := GetTickCount;
      ClearABuffer(1000, 1000);
      EndTime := GetTickCount;
      WriteLn('Elapsed: ', EndTime-BeginTime, ' miliseconds');
    end;
     
    end.
    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.

  11. #11
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    tu peut faire aussi comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ...
    Rowsize := SizeOf(FirstRow[0]) * Length(FirstRow);
    ...
    Move(Pointer(FirstRow)^, Pointer(Buffer[i])^,Rowsize );
    ...
    @+ Phil
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  12. #12
    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 anapurna Voir le message
    salut

    tu peut faire aussi comme ceci
    Bah ça change rien Si ce n'est qu'il faudra réévaluer Length(FirstRow) alors que tu l'as déjà dans Width
    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.

  13. #13
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    je le donne uniquement pour la synthaxe du move.
    cela montre la possibilité de transtypage du tableau en pointeur
    sinon au niveau performance ca doit etre la meme chose

    @+ Phil
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 17
    Points : 9
    Points
    9
    Par défaut
    Messieurs,

    en vous remerciant de votre diligicence...

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 18/02/2010, 15h12
  2. [xsl-fo]Numéroter des tableaux dynamiques
    Par Little_flower dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 23/05/2007, 16h02
  3. Réponses: 6
    Dernier message: 20/02/2007, 17h00
  4. libération des tableaux dynamiques
    Par franckgar dans le forum Langage
    Réponses: 4
    Dernier message: 19/04/2006, 20h49
  5. permutations/combinaisons sur des tableaux dynamiques
    Par pEAk230 dans le forum Langage
    Réponses: 5
    Dernier message: 19/04/2006, 13h18

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