@@ -35,7 +35,7 @@ TStat = record
3535
3636type
3737 // Create a dictionary, now approx 4 mins faster than Generics.Collections.TDictionary
38- TWeatherDictionaryLG = specialize TGHashMapQP<string, TStat >;
38+ TWeatherDictionaryLG = specialize TGHashMapQP<string, PStat >;
3939
4040type
4141 // Create a class to encapsulate the temperature observations of each weather station.
@@ -47,7 +47,8 @@ TWeatherStation = class
4747 procedure ReadMeasurements ;
4848 procedure ReadMeasurementsClassic ;
4949 procedure ReadMeasurementsInChunks (const filename: string);
50- procedure ParseStationAndTempFromChunk (const chunkData: pansichar; const dataSize: int64; const chunkIndex: int64);
50+ procedure ParseStationAndTempFromChunk (const chunkData: pansichar;
51+ const dataSize: int64; const chunkIndex: int64);
5152 procedure ParseStationAndTemp (const line: string);
5253 procedure AddCityTemperatureLG (const cityName: string; const newTemp: int64);
5354 procedure SortWeatherStationAndStats ;
@@ -68,7 +69,8 @@ implementation
6869 The following procedure Written by Székely Balázs for the 1BRC for Object Pascal.
6970 URL: https://github.com/gcarreno/1brc-ObjectPascal/tree/main
7071}
71- function CustomTStringListComparer (AList: TStringList; AIndex1, AIndex2: integer): integer;
72+ function CustomTStringListComparer (AList: TStringList;
73+ AIndex1, AIndex2: integer): integer;
7274var
7375 Pos1, Pos2: integer;
7476 Str1, Str2: string;
@@ -130,10 +132,17 @@ constructor TWeatherStation.Create(const filename: string);
130132end ;
131133
132134destructor TWeatherStation.Destroy;
135+ var
136+ stationName:string;
133137begin
134- // Free TStringLIst dictionary
138+ // Free TStringList dictionary
135139 weatherStationList.Free;
136- // Free the dictionary
140+
141+ // Free the dictionary - 1. Free PStat first
142+ for stationName in self.weatherDictionary.Keys do
143+ Dispose(PStat(self.weatherDictionary.Items[stationName]));
144+
145+ // Free the dictionary - 2. Finally free the container itself
137146 weatherDictionary.Free;
138147end ;
139148
@@ -189,7 +198,7 @@ procedure TWeatherStation.SortWeatherStationAndStats;
189198
190199 for wsKey in weatherDictionary.Keys do
191200 begin
192- self.weatherStationList.Add(wsKey + ' =' + weatherDictionary[wsKey].ToString + ' , ' );
201+ self.weatherStationList.Add(wsKey + ' =' + weatherDictionary[wsKey]^ .ToString + ' , ' );
193202 end ;
194203
195204 self.weatherStationList.CustomSort(@CustomTStringListComparer);
@@ -204,7 +213,7 @@ procedure TWeatherStation.SortWeatherStationAndStats;
204213procedure TWeatherStation.AddCityTemperatureLG (const cityName: string;
205214 const newTemp: int64);
206215var
207- stat: TStat ;
216+ stat: PStat ;
208217begin
209218 // If city name esxists, modify temp as needed
210219 if self.weatherDictionary.Contains(cityName) then
@@ -213,21 +222,21 @@ procedure TWeatherStation.AddCityTemperatureLG(const cityName: string;
213222 stat := self.weatherDictionary[cityName];
214223
215224 // If the temp lower then min, set the new min.
216- if newTemp < stat.min then
217- stat.min := newTemp;
225+ if newTemp < stat^ .min then
226+ stat^ .min := newTemp;
218227
219228 // If the temp higher than max, set the new max.
220- if newTemp > stat.max then
221- stat.max := newTemp;
229+ if newTemp > stat^ .max then
230+ stat^ .max := newTemp;
222231
223232 // Add count for this city.
224- stat.sum := stat.sum + newTemp;
233+ stat^ .sum := stat^ .sum + newTemp;
225234
226235 // Increase the counter
227- stat.cnt := stat.cnt + 1 ;
236+ stat^ .cnt := stat^ .cnt + 1 ;
228237
229238 // Update the stat of this city
230- self.weatherDictionary.AddOrSetValue(cityName, stat);
239+ // self.weatherDictionary.AddOrSetValue(cityName, stat);
231240 { $IFDEF DEBUG}
232241 // Display the line.
233242 WriteLn(' Updated: ' , cityName);
@@ -237,7 +246,12 @@ procedure TWeatherStation.AddCityTemperatureLG(const cityName: string;
237246 // If city name doesn't exist add a new entry
238247 if not self.weatherDictionary.Contains(cityName) then
239248 begin
240- self.weatherDictionary.Add(cityName, TStat.Create(newTemp, newTemp, newTemp, 1 ));
249+ New(stat);
250+ stat^.min := newTemp;
251+ stat^.max := newTemp;
252+ stat^.sum := newTemp;
253+ stat^.cnt := 1 ;
254+ self.weatherDictionary.Add(cityName, stat);
241255
242256 { $IFDEF DEBUG}
243257 // Display the line.
@@ -335,7 +349,8 @@ procedure TWeatherStation.ReadMeasurementsClassic;
335349 end ;
336350end ;
337351
338- procedure TWeatherStation.ParseStationAndTempFromChunk (const chunkData: pansichar; const dataSize: int64; const chunkIndex: int64);
352+ procedure TWeatherStation.ParseStationAndTempFromChunk (const chunkData: pansichar;
353+ const dataSize: int64; const chunkIndex: int64);
339354var
340355 index, lineStart, lineLength: int64;
341356begin
@@ -433,10 +448,10 @@ procedure TWeatherStation.ReadMeasurementsInChunks(const filename: string);
433448// The main algorithm
434449procedure TWeatherStation.ProcessMeasurements ;
435450begin
436- // self.ReadMeasurements;
451+ self.ReadMeasurements;
437452 // self.ReadMeasurementsClassic;
438453 { This chunking method cuts ~ 30 - 40 seconds of processing time from ~6.45 to 6.00}
439- self.ReadMeasurementsInChunks(self.fname);
454+ // self.ReadMeasurementsInChunks(self.fname);
440455 self.SortWeatherStationAndStats;
441456 self.PrintSortedWeatherStationAndStats;
442457end ;
0 commit comments