program Project1;
{$mode objfpc}{$H+}
uses
Classes, SysUtils, fgl, DateUtils, StrUtils;
type
TKeurmeester = class
id: Integer;
naam: String;
end;
{ TKeurmeesterList }
TKeurmeesterList = class(specialize TFPGObjectList<TKeurmeester>)
type
TIDMap = specialize TFPGMap<Integer, Integer>;
private
fIDMap: TIDMap;
public
constructor Create;
destructor Destroy; override;
function Add(aItem: TKeurmeester): Integer;
procedure Delete(aIndex: Integer);
function LocateKeurmeester(id: Integer): Boolean;
function LocateKeurmeesterIn(id: Integer): Boolean;
function LocateKeurmeesterMap(id: Integer): Boolean;
procedure BeginUpdate;
procedure EndUpdate;
end;
{ TKeurmeesterList }
constructor TKeurmeesterList.Create;
begin
inherited Create;
fIDMap := TIDMap.Create;
fIDMap.Duplicates := dupIgnore;
fIDMap.Sorted := True;
end;
destructor TKeurmeesterList.Destroy;
begin
fIDMap.Free;
inherited Destroy;
end;
function TKeurmeesterList.Add(aItem: TKeurmeester): Integer;
begin
Result := inherited Add(aItem);
fIDMap.Add(aItem.id, Result);
end;
procedure TKeurmeesterList.Delete(aIndex: Integer);
var
idx: Integer;
begin
idx := fIDMap.IndexOf(Items[aIndex].id);
if idx >= 0 then
fIDMap.Delete(idx);
inherited Delete(aIndex);
end;
function TKeurmeesterList.LocateKeurmeester(id: Integer): Boolean;
var
i: Integer;
begin
Result := False;
for i := 0 to Count - 1 do
begin
if Items[i].id = id then
begin
Result := True;
break;
end;
end;
end;
function TKeurmeesterList.LocateKeurmeesterIn(id: Integer): Boolean;
var
ki: TKeurmeester;
begin
Result := False;
for ki in Self do
begin
if ki.id = id then
begin
Result := True;
break;
end;
end;
end;
function TKeurmeesterList.LocateKeurmeesterMap(id: Integer): Boolean;
begin
Result := fIDMap.IndexOf(id) >= 0;
end;
procedure TKeurmeesterList.BeginUpdate;
begin
fIDMap.Sorted := False;
end;
procedure TKeurmeesterList.EndUpdate;
begin
fIDMap.Sort;
fIDMap.Sorted := True;
end;
var
kl: TKeurmeesterList;
ki: TKeurmeester;
i, j, n, v: Integer;
valarr: Array [1..4] of Integer = (5378, 478315, 999998, 9999999);
dt: TDateTime;
begin
n := 100000;
dt := Now;
//create list with data
kl := TKeurmeesterList.Create;
kl.BeginUpdate;
for i := 0 to 999999 do
begin
ki := TKeurmeester.Create;
ki.id := i;
ki.naam := 'Item ' + IntToStr(i);
kl.Add(ki);
end;
kl.EndUpdate;
WriteLn('prepare data: ', MillisecondsBetween(Now, dt));
for j := Low(valarr) to High(valarr) do
begin
WriteLn('==========================');
WriteLn('Check ID: ', valarr[j], ' loop count: ', n div StrToInt(Copy('1000', 1, j)));
WriteLn('--------------------------');
//"for in" test
dt := Now;
for i := 0 to n div StrToInt(Copy('1000', 1, j)) do
kl.LocateKeurmeesterIn(valarr[j]);
WriteLn('"for in" loop time in ms: ', MillisecondsBetween(Now, dt), '; result: ', IfThen(kl.LocateKeurmeesterIn(valarr[j]), 'True', 'False'));
//"for to do" test
dt := Now;
for i := 0 to n div StrToInt(Copy('1000', 1, j)) do
kl.LocateKeurmeester(valarr[j]);
WriteLn('"for to do" loop time in ms: ', MillisecondsBetween(Now, dt), '; result: ', IfThen(kl.LocateKeurmeester(valarr[j]), 'True', 'False'));
//map test
dt := Now;
for i := 0 to n div StrToInt(Copy('1000', 1, j)) do
kl.LocateKeurmeesterMap(valarr[j]);
WriteLn('map time in ms: ', MillisecondsBetween(Now, dt), '; result: ', IfThen(kl.LocateKeurmeesterMap(valarr[j]), 'True', 'False'));
end;
kl.Free;
ReadLn;
end.