Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Generic List, große Liste, große Datenstruktur, Geschwindigkeit

  Alt 21. Aug 2015, 08:18
Ja, kleine Veränderung
Delphi-Quellcode:
unit Types.MyTypes;

interface

uses
  System.Generics.Collections;

type
  TMyNextData8 = packed record
  const
    Ident = 'TMyNextData8';
  public
    a: string[ 18 ];
    b: Word;
    c: Word;
  end;

  TMyNextData7 = packed record
  private
  public
    ItemCount: Integer;
    Items : array [ 00 .. 09 ] of TMyNextData8;
  end;

type
  TMyNextData6 = packed record
  const
    Ident = 'TMyNextData6';
  public
    a: LongWord;
    b: string[ 18 ];
    c: string[ 40 ];
    d: Double;
    e: string[ 03 ];
    f: string[ 04 ];
    g: string[ 01 ];
    h: string[ 10 ];
    i: string[ 01 ];

    j: LongWord;
    k: string[ 12 ];
    l: string[ 08 ];
  end;

  TMyNextData5 = packed record
  private
  public
    ItemCount: Integer;
    Items : array [ 0 .. 09 ] of TMyNextData6;
  end;

type
  TMyNextData4 = packed record
  const
    Ident = 'TMyNextData4';
  public
    a: Word;
    b: LongWord;
    c: string[ 12 ];
    d: string[ 12 ];
    e: string[ 12 ];
    f: string[ 08 ];
    g: string[ 10 ];
    h: LongWord;
  end;

type
  TMyNextData3 = packed record
  const
    MaxAnz = 10;
  private
  public
    ItemCount: Integer;
    Items : array [ 00 .. MaxAnz - 1 ] of TMyNextData4;
  end;

type
  TMyNextData = packed record
  const
    MyStr = 'TMyNextData';
  public
    a: string[ 16 ];

    b: TDate;
    c: TTime;
    d: LongWord;

    e: LongWord;
    f: string[ 12 ];
    g: string[ 12 ];
    h: string[ 12 ];
    i: TMyNextData3;

    j: string[ 06 ];
    k: string[ 18 ];
    l: string[ 40 ];
    m: Double;
    n: string[ 03 ];
    o: string[ 04 ];
    p: string[ 10 ];
    q: TMyNextData5;

    r: LongWord;
    s: string[ 12 ];

    t: string[ 08 ];
    u: string[ 08 ];

    v: string[ 04 ];
    w: TDate;
    x: string[ 10 ];

    y : string[ 10 ];
    z : string[ 01 ];
    aa: string[ 01 ];
    bb: string[ 10 ];

    cc: TMyNextData7;

    dd: array [ 0 .. 49 ] of Byte;
  end;

type
  TMyData = packed record
  const
    MyStr = 'TMyData';
  public
    ID : LongWord;
    ID2 : LongWord;
    ID3 : LongWord;
    First : Boolean;
    Second: Boolean;
    Third : Boolean;

    a: LongWord;
    b: LongWord;
    c: Byte;
    d: Byte;
    e: Word;
    f: TMyNextData;

    g: Word;
    h: LongWord;
    i: string[ 10 ];
    j: string[ 18 ];
    k: Byte;
    l: string[ 1 ];
    m: string[ 10 ];
    n: LongWord;
    o: TDateTime;

    p, q, r, s, t, u, v, w, x: Word;

    y: string[ 10 ];
    z: string[ 4 ];

    aa, bb: Byte;

    cc: string[ 8 ];

    dd: string[ 01 ];
    ee: Word;
    ff: Boolean;

    gg, hh: Byte;

    ii: Byte;
    jj: LongWord;

    kk: Word;
    ll: Word;
    mm: Word;
    nn: array [ 0 .. 93 ] of Byte;
    oo: TDateTime;

    pp: TDateTime;
    qq: TDateTime;

    procedure Clear;
  end;

type
  TMyListe = class( TList<TMyData> )
  private
  public
    function GetFirstItems( var aFirstList: TMyListe ): Integer;
  end;

implementation

{ TMyListe }

function TMyListe.GetFirstItems( var aFirstList: TMyListe ): Integer;
var
  i : Integer;
  tmpData: TMyData;
begin
  if Assigned( aFirstList )
  then
    begin
      aFirstList.Clear;
      i := 0;
      while i < Self.Count do
        begin
          if ( Self.Items[ i ].First )
          then
            begin
              tmpData := Self.Items[ i ];
              Self.Delete( i );
              aFirstList.Add( tmpData );
            end
          else
            begin
              inc( i );
            end;
        end;
    end;
  Result := aFirstList.Count;
end;

{ TMyData }

procedure TMyData.Clear;
begin
  FillChar( Self, SizeOf( Self ), 0 );
end;

end.
Delphi-Quellcode:
unit Types.MyClassTypes;

interface

uses
  System.Generics.Collections,
  System.SysUtils,
  Types.MyTypes;

type
  TMyDataObj = class
  const
    MyStr = 'TMyDataObj';
  public
    ID : LongWord;
    ID2 : LongWord;
    ID3 : LongWord;
    First : Boolean;
    Second: Boolean;
    Third : Boolean;

    a: LongWord;
    b: LongWord;
    c: Byte;
    d: Byte;
    e: Word;
    f: TMyNextData;

    g: Word;
    h: LongWord;
    i: string[ 10 ];
    j: string[ 18 ];
    k: Byte;
    l: string[ 1 ];
    m: string[ 10 ];
    n: LongWord;
    o: TDateTime;

    p, q, r, s, t, u, v, w, x: Word;

    y: string[ 10 ];
    z: string[ 4 ];

    aa, bb: Byte;

    cc: string[ 8 ];

    dd: string[ 01 ];
    ee: Word;
    ff: Boolean;

    gg, hh: Byte;

    ii: Byte;
    jj: LongWord;

    kk: Word;
    ll: Word;
    mm: Word;
    nn: array [ 0 .. 93 ] of Byte;
    oo: TDateTime;

    pp: TDateTime;
    qq: TDateTime;

  end;

type
  TMyObjListe = class( TObjectList<TMyDataObj> )
  private
  public
    function GetFirstItems( const aFirstList: TMyObjListe ): Integer;
  end;

implementation

{ TMyObjListe }

function TMyObjListe.GetFirstItems( const aFirstList: TMyObjListe ): Integer;
var
  i : Integer;
  tmpData: TMyDataObj;
begin
  if not Assigned( aFirstList )
  then
    raise EArgumentNilException.Create( 'aFirstList' );

  aFirstList.Clear;
  i := 0;
  while i < Self.Count do
    begin
      if ( Self.Items[ i ].First )
      then
        begin
          tmpData := Self.Items[ i ];
          aFirstList.Add( Self.Extract( tmpData ) );
        end
      else
        begin
          inc( i );
        end;
    end;
  Result := aFirstList.Count;
end;

end.
Und nun
Delphi-Quellcode:
unit Forms.MainForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class( TForm )
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click( Sender: TObject );
    procedure Button2Click( Sender: TObject );
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  System.Diagnostics,
  Types.MyTypes, Types.MyClassTypes;

procedure TForm1.Button1Click( Sender: TObject );
var
  AllDataList : TMyListe;
  FirstList : TMyListe;
  i : Integer;
  aData : TMyData;
  aMes1, aMes2: TStopWatch;
begin
  AllDataList := TMyListe.Create;
  FirstList := TMyListe.Create;

  aMes1.Create;
  aMes1.Reset;
  aMes1.Start;

  try
    // 5000 Einträge erstellen (First=True)
    for i := 1 to 5000 do
      begin
        aData.Clear;
        aData.ID := i;
        aData.First := True;

        AllDataList.Add( aData );
      end;

    // 5000 Einträge erstellen (First=False)
    for i := 1 to 5000 do
      begin
        aData.Clear;
        aData.ID2 := i;
        aData.First := False;

        AllDataList.Add( aData );
      end;

    // Schritt1: Rootliste füllen
    aMes2.Create;
    aMes2.Reset;
    aMes2.Start;
    AllDataList.GetFirstItems( FirstList );
    aMes2.Stop;

  finally
    if Assigned( FirstList )
    then
      begin
        FirstList.Clear;
        FreeAndNil( FirstList );
      end;

    if Assigned( AllDataList )
    then
      begin
        AllDataList.Clear;
        FreeAndNil( AllDataList );
      end;
  end;

  aMes1.Stop;
  ShowMessage( 'Zeitmessung 1 (s): ' + IntToStr( Round( aMes1.ElapsedMilliseconds / 1000 ) ) );

  ShowMessage( 'Zeitmessung 2 (s): ' + IntToStr( Round( aMes2.ElapsedMilliseconds / 1000 ) ) );
end;

procedure TForm1.Button2Click( Sender: TObject );
var
  AllDataList : TMyObjListe;
  FirstList : TMyObjListe;
  i : Integer;
  aData : TMyDataObj;
  aMes1, aMes2: TStopWatch;
begin
  AllDataList := TMyObjListe.Create( True );
  FirstList := TMyObjListe.Create( True );

  aMes1.Create;
  aMes1.Reset;
  aMes1.Start;

  try
    // 5000 Einträge erstellen (First=True)
    for i := 1 to 5000 do
      begin
        aData := TMyDataObj.Create;
        aData.ID := i;
        aData.First := True;

        AllDataList.Add( aData );
      end;

    // 5000 Einträge erstellen (First=False)
    for i := 1 to 5000 do
      begin
        aData := TMyDataObj.Create;
        aData.ID2 := i;
        aData.First := False;

        AllDataList.Add( aData );
      end;

    // Schritt1: Rootliste füllen
    aMes2.Create;
    aMes2.Reset;
    aMes2.Start;
    AllDataList.GetFirstItems( FirstList );
    aMes2.Stop;

  finally
    FreeAndNil( FirstList );
    FreeAndNil( AllDataList );
  end;

  aMes1.Stop;
  ShowMessage( 'Zeitmessung 1 (s): ' + IntToStr( Round( aMes1.ElapsedMilliseconds / 1000 ) ) );

  ShowMessage( 'Zeitmessung 2 (s): ' + IntToStr( Round( aMes2.ElapsedMilliseconds / 1000 ) ) );
end;

end.
dauert das nur noch 0 Sekunden
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat