Skip to content

Commit 05111ac

Browse files
committed
Updated - Used baseline's rounding method.
- Removed string split function, used Pos and Copy instead.
1 parent 3435441 commit 05111ac

File tree

2 files changed

+77
-34
lines changed

2 files changed

+77
-34
lines changed

baseline/Lazarus/src/baseline.lpi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@
112112
<OtherUnitFiles Value="../../Common"/>
113113
<UnitOutputDirectory Value="../../../bin/lib/$(TargetCPU)-$(TargetOS)"/>
114114
</SearchPaths>
115+
<Linking>
116+
<Debugging>
117+
<DebugInfoType Value="dsDwarf2Set"/>
118+
</Debugging>
119+
</Linking>
115120
</CompilerOptions>
116121
<Debugging>
117122
<Exceptions Count="3">

entries/ikelaiah/src/weatherstation.pas

Lines changed: 72 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,65 +10,88 @@ interface
1010
{$ENDIF}
1111
Classes,
1212
SysUtils,
13-
Generics.Collections
13+
Generics.Collections,
14+
Math
1415
{$IFDEF DEBUG}
1516
, Stopwatch
1617
{$ENDIF}
17-
;
18+
;
1819

1920
type
2021
// Create a record of temperature stats
2122
TStat = record
2223
var
23-
min: single;
24-
max: single;
25-
sum: single;
26-
count: word;
24+
min: int64;
25+
max: int64;
26+
sum: int64;
27+
Count: int64;
28+
private
29+
function RoundEx(x: double): double; // Borrowed from the baseline program
30+
function PascalRound(x: double): double; // Borrowed from the baseline program
2731
public
28-
constructor Create(newMin: single;
29-
newMax: single;
30-
newSum: single;
31-
newCount: word);
32+
constructor Create(newMin: int64; newMax: int64; newSum: int64; newCount: int64);
3233
function ToString: string;
34+
3335
end;
3436

3537
type
3638
// Create a dictionary
3739
TWeatherDictionary = specialize TDictionary<string, TStat>;
3840

39-
40-
{// A helper function to add a city temperature into the TWeatherDictionary
41-
procedure AddCityTemperature(cityName: string;
42-
newTemp: single;
43-
var weatherDictionary: TWeatherDictionary);
44-
}
45-
4641
// The main algorithm to process the temp measurements from various weather station
4742
procedure ProcessTempMeasurements(filename: string);
4843

4944

5045
implementation
5146

52-
constructor TStat.Create(newMin: single;
53-
newMax: single;
54-
newSum: single;
55-
newCount: word);
47+
function TStat.RoundEx(x: double): double;
48+
begin
49+
Result := PascalRound(x * 10.0) / 10.0;
50+
end;
51+
52+
function TStat.PascalRound(x: double): double;
53+
var
54+
t: double;
55+
begin
56+
//round towards positive infinity
57+
t := Trunc(x);
58+
if (x < 0.0) and (t - x = 0.5) then
59+
begin
60+
// Do nothing
61+
end
62+
else if Abs(x - t) >= 0.5 then
63+
begin
64+
t := t + Math.Sign(x);
65+
end;
66+
67+
if t = 0.0 then
68+
Result := 0.0
69+
else
70+
Result := t;
71+
end;
72+
73+
constructor TStat.Create(newMin: int64; newMax: int64; newSum: int64; newCount: int64);
5674
begin
5775
self.min := newMin;
5876
self.max := newMax;
5977
self.sum := newSum;
60-
self.count := newCount;
78+
self.Count := newCount;
6179
end;
6280

6381
function TStat.ToString: string;
82+
var
83+
minR, meanR, maxR: double; // Store the rounded values prior saving to TStringList.
6484
begin
6585
{$IFDEF DEBUG}
6686
Result := Format('Min: %.1f; Mean: %.1f; Maxp: %.1f; Sum: %.1f; Count %d',
6787
[self.min, (self.sum / self.Count), self.max,
6888
self.sum, self.Count]);
6989
{$ENDIF DEBUG}
7090
// Result := Format('%.1f/%.1f/%.1f', [self.min, (self.sum / self.count), self.max]);
71-
Result := FormatFloat('0.0', self.min) + '/' + FormatFloat('0.0', (self.sum/self.count)) + '/' + FormatFloat('0.0', self.max)
91+
minR := RoundEx(self.min / 10);
92+
maxR := RoundEx(self.max / 10);
93+
meanR := RoundEx(self.sum / self.Count / 10);
94+
Result := FormatFloat('0.0', minR) + '/' + FormatFloat('0.0', meanR) + '/' + FormatFloat('0.0', maxR);
7295

7396
end;
7497

@@ -78,10 +101,11 @@ function TStat.ToString: string;
78101
The following procedure Written by Székely Balázs for the 1BRC for Object Pascal.
79102
URL: https://github.com/gcarreno/1brc-ObjectPascal/tree/main
80103
}
81-
function CustomTStringListComparer(AList: TStringList; AIndex1, AIndex2: Integer): Integer;
104+
function CustomTStringListComparer(AList: TStringList;
105+
AIndex1, AIndex2: integer): integer;
82106
var
83-
Pos1, Pos2: Integer;
84-
Str1, Str2: String;
107+
Pos1, Pos2: integer;
108+
Str1, Str2: string;
85109
begin
86110
Result := 0;
87111
Str1 := AList.Strings[AIndex1];
@@ -92,13 +116,12 @@ function CustomTStringListComparer(AList: TStringList; AIndex1, AIndex2: Integer
92116
begin
93117
Str1 := Copy(Str1, 1, Pos1 - 1);
94118
Str2 := Copy(Str2, 1, Pos2 - 1);
95-
Result := CompareStr(Str1, Str2);
119+
Result := CompareStr(Str1, Str2);
96120
end;
97121
end;
98122

99-
procedure AddCityTemperature(cityName: string;
100-
newTemp: single;
101-
var weatherDictionary: TWeatherDictionary);
123+
124+
procedure AddCityTemperature(cityName: string; newTemp: int64; var weatherDictionary: TWeatherDictionary);
102125
var
103126
stat: TStat;
104127
begin
@@ -142,11 +165,11 @@ procedure AddCityTemperature(cityName: string;
142165
procedure ProcessTempMeasurements(filename: string);
143166
var
144167
wd: TWeatherDictionary;
145-
line, ws: string;
146-
lineSeparated: array of string;
168+
line, ws, recordedTemp: string;
147169
weatherStationList: TStringList;
148170
textFile: System.TextFile;
149171
isFirstKey: boolean = True;
172+
delimiterPos: integer;
150173
begin
151174

152175
// Start a timer
@@ -172,12 +195,26 @@ procedure ProcessTempMeasurements(filename: string);
172195
begin
173196
// Read a line
174197
ReadLn(textFile, line);
198+
175199
// If the line start with #, then continue/skip.
176200
if (line[1] = '#') then continue;
177201

202+
// Get position of the delimiter
203+
delimiterPos := Pos(';', line);
204+
178205
// Else, add an entry into the dictionary.
179-
lineSeparated := line.Split([';']);
180-
AddCityTemperature(lineSeparated[0], StrToFloat(lineSeparated[1]), wd);
206+
// Get the weather station name
207+
// Using Copy ans POS - as suggested by Gemini AI.
208+
// This made the program 3 mins fater when processing 1 billion rows.
209+
ws := Copy(line, 1, delimiterPos - 1);
210+
211+
// Get the temperature recorded, as string, remove '.' from string float
212+
// because we want to save it as int64.
213+
recordedTemp := Copy(line, delimiterPos + 1, Length(line));
214+
recordedTemp := StringReplace(recordedTemp, '.', '', [rfReplaceAll, rfIgnoreCase]);
215+
216+
// Add the weather station and the recorded temp (as int64) in the TDictionary
217+
AddCityTemperature(ws, StrToInt64(recordedTemp), wd);
181218

182219
end; // end while loop reading line at a time
183220

@@ -190,6 +227,7 @@ procedure ProcessTempMeasurements(filename: string);
190227
end; // End of file reading ////////////////////////////////////////////////
191228

192229
// Format and sort weather station by name and temp stat ///////////////////
230+
ws:='';
193231
for ws in wd.Keys do
194232
begin
195233
weatherStationList.Add(ws + '=' + wd[ws].ToString);

0 commit comments

Comments
 (0)