diff --git a/entries/ghatem-fpc/src/onebrc.pas b/entries/ghatem-fpc/src/onebrc.pas index a2e517b..481d03c 100644 --- a/entries/ghatem-fpc/src/onebrc.pas +++ b/entries/ghatem-fpc/src/onebrc.pas @@ -35,12 +35,13 @@ function RoundExDouble(const ATemp: Double): Double; inline; TMyDictionary = class private FHashes: TKeys; - FData : TValues; + FValues: TValues; + FRecords: array of TStationData; procedure InternalFind(const aKey: Cardinal; out aFound: Boolean; out aIndex: Integer); public constructor Create; property Keys: TKeys read FHashes; - property Values: TValues read FData; + property Values: TValues read FValues; function TryGetValue (const aKey: Cardinal; out aValue: PStationData): Boolean; inline; procedure Add (const aKey: Cardinal; const aValue: PStationData); inline; end; @@ -94,9 +95,6 @@ TBRCThread = class (TThread) implementation -uses - CRC; - const c0ascii: ShortInt = 48; @@ -169,9 +167,16 @@ procedure TMyDictionary.InternalFind(const aKey: Cardinal; out aFound: Boolean; end; constructor TMyDictionary.Create; +var + I: Integer; begin SetLength (FHashes, cDictSize); - SetLength (FData, cDictSize); + SetLength (FValues, cDictSize); + SetLength (FRecords, cDictSize); + + for I := 0 to cDictSize - 1 do begin + FValues[I] := @FRecords[I]; + end; end; function TMyDictionary.TryGetValue(const aKey: Cardinal; out aValue: PStationData): Boolean; @@ -179,11 +184,7 @@ function TMyDictionary.TryGetValue(const aKey: Cardinal; out aValue: PStationDat vIdx: Integer; begin InternalFind (aKey, Result, vIdx); - - if Result then - aValue := FData[vIdx] - else - aValue := nil; + aValue := FValues[vIdx]; end; procedure TMyDictionary.Add(const aKey: Cardinal; const aValue: PStationData); @@ -194,7 +195,7 @@ procedure TMyDictionary.Add(const aKey: Cardinal; const aValue: PStationData); InternalFind (aKey, vFound, vIdx); if not vFound then begin FHashes[vIdx] := aKey; - FData[vIdx] := aValue; + FValues[vIdx] := aValue; end else raise Exception.Create ('TMyDict: cannot add, duplicate key'); @@ -351,7 +352,6 @@ procedure TOneBRC.ProcessData (aThreadNb: UInt16; aStartIdx: Int64; aEndIdx: Int SetString(vStation, pAnsiChar(@FData[vLineStart]), vLenStationName); // pre-allocated array of records instead of on-the-go allocation - new(vData); vData^.Min := vTemp; vData^.Max := vTemp; vData^.Sum := vTemp; @@ -420,8 +420,8 @@ procedure TOneBRC.GenerateOutput; try vStations.BeginUpdate; for vData in FStationsDicts[0].Values do begin - // nil value means empty slot: skip - if vData <> nil then + // count = 0 means empty slot: skip + if vData^.Count <> 0 then vStations.Add(vData^.Name); end; vStations.EndUpdate;