Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

Re: In einem unsortierten array min. und max. herausfinden.

  Alt 16. Mai 2009, 17:04
jupp, und diese machen es genauso, sind also etwa gleich schnell.

hier gibt es einfach nicht viel zum Optimieren, da die größte Bremse (das Kopieren der Werte, in die CPU) immer erhalten bleibt.
Delphi-Quellcode:
uses Math;

procedure TForm1.Button1Click(Sender: TObject);
const MinInt = Low(Integer);
var a: Array of Integer;
  i, min, max: Integer;
  p: PInteger;
  q1, q2, f: Int64;
  s: String;
begin
  SetLength(a, $10ffffff);
  // $1ffffffc dürfte etwa das Maximum von rund 2 GB sein.
  // Hab hier das Programm allerdings nur im 2 GB-Mode laufen, weswegen
  // ich nicht an 2 GB rankomm, da die DLLs + EXE + MemoryManager ja
  // einen Teil schon belegt haben.
  For i := 0 to High(a) do a[i] := Random(MaxInt);

  QueryPerformanceFrequency(f);
  s := '';

  QueryPerformanceCounter(q1);
  min := MinIntValue(a);
  max := MaxIntValue(a);
  QueryPerformanceCounter(q2);
  If min = max Then ;
  s := Format('%s - 1: %f ms', [s, (q2 - q1) * 1000 / f]);

  QueryPerformanceCounter(q1);
  min := a[0];
  max := a[0];
  For i := 1 to High(a) do Begin
    If a[i] < min Then min := a[i];
    If a[i] > max Then max := a[i];
  End;
  QueryPerformanceCounter(q2);
  If min = max Then ;
  s := Format('%s - 2: %f ms', [s, (q2 - q1) * 1000 / f]);

  QueryPerformanceCounter(q1);
  min := MaxInt;
  max := MinInt;
  For i := 0 to High(a) do
    If a[i] < min Then min := a[i]
    Else If a[i] > max Then max := a[i];
  QueryPerformanceCounter(q2);
  If min = max Then ;
  s := Format('%s - 3: %f ms', [s, (q2 - q1) * 1000 / f]);

  QueryPerformanceCounter(q1);
  min := MaxInt;
  max := MinInt;
  P := Pointer(a);
  For i := High(a) downto 0 do Begin
    If P^ < min Then min := P^
    Else If P^ > max Then max := P^;
    Inc(P);
  End;
  QueryPerformanceCounter(q2);
  If min = max Then ;
  s := Format('%s - 4: %f ms', [s, (q2 - q1) * 1000 / f]);

  QueryPerformanceCounter(q1);
  min := MaxInt;
  max := MinInt;
  P := Pointer(a);
  For i := High(a) downto 0 do Begin
    If P^ < min Then min := P^;
    Inc(P);
  End;
  P := Pointer(a);
  For i := High(a) downto 0 do Begin
    If P^ > max Then max := P^;
    Inc(P);
  End;
  QueryPerformanceCounter(q2);
  If min = max Then ;
  s := Format('%s - 5: %f ms', [s, (q2 - q1) * 1000 / f]);

  QueryPerformanceCounter(q1);
  min := MaxInt;
  max := MinInt;
  P := Pointer(a);
  For i := High(a) downto 0 do Begin
    If P^ < min Then Begin
      min := P^;
      If min = MinInt Then Break;
    End;
    Inc(P);
  End;
  P := Pointer(a);
  For i := High(a) downto 0 do Begin
    If P^ > max Then Begin
      max := P^;
      If max = MaxInt Then Break;
    End;
    Inc(P);
  End;
  QueryPerformanceCounter(q2);
  If min = max Then ;
  s := Format('%s - 6: %f ms', [s, (q2 - q1) * 1000 / f]);

  QueryPerformanceCounter(q1);
  ASM
    PUSH EDI
    PUSH EBX

    MOV EAX, &MinInt
    MOV EDX, &MaxInt
    MOV EDI, &a
    TEST EDI, EDI
    JZ @@none
    MOV ECX, [EDI - 4]
    @@loop:
    MOV EBX, [EDI + ECX * 4]

    CMP EAX, EBX
    JGE @@greater
    MOV EAX, EBX
    @@greater:

    CMP EDX, EBX
    JLE @@lower
    MOV EDX, EBX
    @@lower:

    LOOP @@loop

    @@none:
    MOV &min, EAX
    MOV &max, EDX

    POP EBX
    POP EDI
  End;
  QueryPerformanceCounter(q2);
  If min = max Then ;
  s := Format('%s - 7: %f ms', [s, (q2 - q1) * 1000 / f]);

  ShowMessageFmt('%d : %d MB %s', [Length(a), (Length(a) * SizeOf(Integer)) shr 20, s]);
end;
Zitat von Satty67:
Wie messt Ihr das?
wie messen wir was?


PS:
Zitat von Unit Math:
Delphi-Quellcode:
function MinIntValue(const Data: array of Integer): Integer;
var
  I: Integer;
begin
  Result := Data[Low(Data)];
  for I := Low(Data) + 1 to High(Data) do
    if Result > Data[I] then
      Result := Data[I];
end;
$2B or not $2B
  Mit Zitat antworten Zitat