Einzelnen Beitrag anzeigen

Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#13

AW: RTTI: generische TObjectList erkennen

  Alt 3. Nov 2021, 15:30
Diese .List Property ist ja schon immer™ der Zugriff auf das interne Array gewesen.
Auch schon bei der alten System.Classes.TList.
Nutze ich in der Regel auch in Schleifen, wenn von 0 bis Count - 1 iteriert wird, um die GetItem-Funktion zu umgehen.
Die mag zwar je nach Delphi-Version zwar inline markiert sein, aber es wird unnötig Index >= FCount geprüft.
Hat idR keinerlei Auswirkung auf die Performance - hier mal das Ergebnis von ner hingeschluderten Benchmark:

Code:
-------------------------------------------------------
Benchmark                 Time            CPU  Iterations
-------------------------------------------------------------
RTL-getter/10           9,31 ns        9,28 ns    64000000 
RTL-getter/100           114 ns         115 ns     6400000 
RTL-getter/1000         1150 ns        1147 ns      640000 
RTL-getter/10000       11550 ns       11475 ns       64000 
RTL-getter/100000     115873 ns      117188 ns        5600 
RTL-list/10             9,16 ns        9,21 ns    74666667 
RTL-list/100             113 ns         115 ns     6400000 
RTL-list/1000           1151 ns        1144 ns      560000 
RTL-list/10000         11577 ns       11719 ns       64000 
RTL-list/100000       115813 ns      117188 ns        6400
Sollte man übrigens runtime packages nutzen, fällt das inlining weg und der Zugriff auf .List wird nicht mehr geinlined und jedesmal aufgerufen, was diesen Ansatz ca 10mal langsamer macht, der nicht mehr geinlinete Getter hingegen kostet nur ca 50% mehr. Dieselbe Benchmark mit rtl als runtime package:

Code:
-------------------------------------------------------
Benchmark                 Time            CPU  Iterations
-------------------------------------------------------------
RTL-getter/10           16,9 ns        16,9 ns    40727273 
RTL-getter/100           169 ns         169 ns     4072727 
RTL-getter/1000         1639 ns        1650 ns      407273 
RTL-getter/10000       16257 ns       16392 ns       44800 
RTL-getter/100000     163355 ns      161122 ns        4073 
RTL-list/10              146 ns         146 ns     4480000 
RTL-list/100            1461 ns        1475 ns      497778 
RTL-list/1000          14593 ns       14300 ns       44800 
RTL-list/10000        145201 ns      142997 ns        4480 
RTL-list/100000      1452860 ns     1443273 ns         498
Benchmark Code:

Delphi-Quellcode:
uses
  Spring.Benchmark,
  Generics.Collections;

procedure RTLGetter(const state: TState);
var
  list: TList<Integer>;
  count, i: Integer;
  sum: Integer;
begin
  list := TList<Integer>.Create;
  count := state[0];
  for i := 1 to count do
    list.Add(i);

  sum := 0;
  while state.KeepRunning do
  begin
    sum := 0;

    for i := 0 to list.Count - 1 do
      Inc(sum, list[i]);
  end;

  state.Counters['sum'] := sum;
  list.Free;
end;

procedure RTLList(const state: TState);
var
  list: TList<Integer>;
  count, i: Integer;
  sum: Integer;
begin
  list := TList<Integer>.Create;
  count := state[0];
  for i := 1 to count do
    list.Add(i);

  sum := 0;
  while state.KeepRunning do
  begin
    sum := 0;

    for i := 0 to list.Count - 1 do
      Inc(sum, list.List[i]);
  end;

  state.Counters['sum'] := sum;
  list.Free;
end;

begin
  Benchmark(RTLGetter, 'RTL-getter').RangeMultiplier(10).Range(10, 100000);
  Benchmark(RTLList, 'RTL-list').RangeMultiplier(10).Range(10, 100000);

  Benchmark_Main();
end.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie ( 3. Nov 2021 um 15:37 Uhr)
  Mit Zitat antworten Zitat