Skip to content

Commit 6d8357d

Browse files
committed
refactor: Fastest version thanks to @paweld
1 parent 38c323a commit 6d8357d

File tree

4 files changed

+91
-19
lines changed

4 files changed

+91
-19
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ The task is to write an Object Pascal program which reads the file, calculates t
2929
{Abha=-23.0/18.0/59.2, Abidjan=-16.2/26.0/67.3, Abéché=-10.0/29.4/69.0, Accra=-10.1/26.4/66.4, Addis Ababa=-23.7/16.0/67.0, Adelaide=-27.8/17.3/58.5, ...}
3030
```
3131

32+
## Honout Mentions
33+
34+
I'd like to thank [@paweld](https://github.com/paweld) for taking us from my miserable 20m attempt, to a woping 3m, beating the [Python script](https://github.com/gunnarmorling/1brc/blob/main/src/main/python/create_measurements.py) by about 2 minutes.
35+
3236
## Links
3337

3438
The original repository: https://github.com/gunnarmorling/1brc

generator/Common/generate.common.pas

+58-17
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ TGenerator = class(TObject)
2525
FStationNames: TStringList;
2626

2727
procedure BuildStationNames;
28-
function GenerateProgressBar(APosition, AMax, ALength:Int64):String;
28+
function GenerateProgressBar(
29+
APBPosition, APBMax, APBWIdth, AFileSize:Int64;
30+
ATimeElapsed: TDateTime
31+
):String;
2932
protected
3033
public
3134
constructor Create(AInputFile, AOutputFile: String; ALineCount: Int64);
@@ -119,28 +122,37 @@ procedure TGenerator.BuildStationNames;
119122
WriteLn;
120123
end;
121124

122-
function TGenerator.GenerateProgressBar(APosition, AMax, ALength: Int64
123-
): String;
125+
function TGenerator.GenerateProgressBar(
126+
APBPosition, APBMax, APBWIdth, AFileSize: Int64;
127+
ATimeElapsed: TDateTime
128+
): String;
124129
var
125130
percentDone: Double;
126131
filled: Integer;
127132
begin
128-
percentDone:= (100 * APosition) / AMax;
129-
filled:= (ALength * APosition ) div AMax;
133+
percentDone:= (100 * APBPosition) / APBMax;
134+
filled:= (APBWIdth * APBPosition ) div APBMax;
130135
Result:= '[';
131136
Result:= Result + StringOfChar('#', filled);
132-
Result:= Result + StringOfChar('-', ALength - filled);
137+
Result:= Result + StringOfChar('-', APBWIdth - filled);
133138
Result:= Result + Format('] %5.2f %%', [ percentDone ]);
139+
Result:= Result + Format(' lines: %.n, file size: %.n, elapsed: %s ', [
140+
Double(APBPosition),
141+
Double(AFileSize),
142+
FormatDateTime('n" min, "s" sec"', ATimeElapsed)
143+
]);
134144
end;
135145

136146
procedure TGenerator.Generate;
137147
var
138148
index, progressBatch: Int64;
139149
stationId: Int64;
140-
randomTemp: Double;
150+
randomTemp: Integer;
151+
randomTempStr: String[4];
141152
outputFileStream: TFileStream;
142153
outputBufWriter: TWriteBufStream;
143-
line: String;
154+
line, randomTempFinal: String;
155+
start: TDateTime;
144156
begin
145157
// Randomize sets this variable depending on the current time
146158
// We just set it to our own value
@@ -157,32 +169,61 @@ procedure TGenerator.Generate;
157169
//outputBufWriter:= TWriteBufStream.Create(outputFileStream, 4*1024);
158170
outputBufWriter:= TWriteBufStream.Create(outputFileStream, 64*1024);
159171
try
160-
Write(GenerateProgressBar(1, FLineCount, 50), #13);
172+
start:= Now;
173+
Write(GenerateProgressBar(1, FLineCount, 50, 0, Now - start), #13);
161174
// Generate the file
162175
for index:= 1 to FLineCount do
163176
begin
164177
stationId:= Random(FStationNames.Count);
165-
randomTemp:= Random * (2 * cHottestTemp) - cHottestTemp;
166-
line:= Format('%s;%s'#13#10, [
167-
FStationNames[stationId],
168-
FormatFloat('#0.0', randomTemp)
169-
]);
178+
// This is all paweld magic:
179+
// From here
180+
randomTemp:= Random(1000);
181+
randomTempStr:= IntToStr(randomTemp);
182+
case Ord(randomTempStr[0]) of
183+
1: randomTempFinal := '0.' + randomTempStr;
184+
2: randomTempFinal := randomTempStr[1] + '.' + randomTempStr[2];
185+
3: randomTempFinal := randomTempStr[1] + randomTempStr[2] + '.' + randomTempStr[3];
186+
4: randomTempFinal := randomTempStr[1] + randomTempStr[2] + randomTempStr[3] + '.' + randomTempStr[4];
187+
end;
188+
if (randomTemp <> 0) and (Random(2) = 1) then
189+
randomTempFinal := '-' + randomTempFinal;
190+
line := line + FStationNames[stationId] + ';' + randomTempFinal + #13#10;
170191
//Write(line);
171-
outputBufWriter.WriteBuffer(line[1], Length(line));
192+
if index mod 10000 = 0 then
193+
begin
194+
outputFileStream.WriteBuffer(line[1], Length(line));
195+
line := '';
196+
end;
197+
// To here
172198
Dec(progressBatch);
173199
if progressBatch = 0 then
174200
begin
175-
Write(GenerateProgressBar(index, FLineCount, 50), #13);
201+
Write(GenerateProgressBar(
202+
index,
203+
FLineCount,
204+
50,
205+
outputFileStream.Size,
206+
Now - start
207+
), #13);
176208
progressBatch:= floor(FLineCount * (batchPercent / 100));
177209
end;
178210
end;
211+
if line <> '' then
212+
begin
213+
outputFileStream.WriteBuffer(line[1], Length(line));
214+
end;
179215
finally
180216
outputBufWriter.Free;
181217
end;
182218
finally
219+
WriteLn;
220+
WriteLn;
221+
WriteLn(Format('Done: file size: %.n, elapsed: %s', [
222+
Double(outputFileStream.Size),
223+
FormatDateTime('n" min, "s" sec"', Now - start)
224+
]));
183225
outputFileStream.Free;
184226
end;
185-
WriteLn;
186227
end;
187228

188229
end.

generator/Common/version.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
'0.1'
1+
'0.2'

generator/Lazarus/src/generator.lpi

+28-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<UseAppBundle Value="False"/>
1515
<ResourceType Value="res"/>
1616
</General>
17-
<BuildModes Count="4">
17+
<BuildModes Count="5">
1818
<Item1 Name="Default" Default="True"/>
1919
<Item2 Name="Debug">
2020
<CompilerOptions>
@@ -72,6 +72,7 @@
7272
<Debugging>
7373
<GenerateDebugInfo Value="False"/>
7474
<RunWithoutDebug Value="True"/>
75+
<StripSymbols Value="True"/>
7576
</Debugging>
7677
<LinkSmart Value="True"/>
7778
</Linking>
@@ -90,12 +91,38 @@
9091
</SearchPaths>
9192
<Linking>
9293
<Debugging>
94+
<RunWithoutDebug Value="True"/>
9395
<DebugInfoType Value="dsDwarf3"/>
9496
<UseValgrind Value="True"/>
9597
</Debugging>
9698
</Linking>
9799
</CompilerOptions>
98100
</Item4>
101+
<Item5 Name="Perf">
102+
<CompilerOptions>
103+
<Version Value="11"/>
104+
<Target>
105+
<Filename Value="../../../bin/generator"/>
106+
</Target>
107+
<SearchPaths>
108+
<IncludeFiles Value="$(ProjOutDir);../../Common"/>
109+
<OtherUnitFiles Value="../../Common"/>
110+
<UnitOutputDirectory Value="../../../bin/lib/$(TargetCPU)-$(TargetOS)"/>
111+
</SearchPaths>
112+
<CodeGeneration>
113+
<Optimizations>
114+
<OptimizationLevel Value="0"/>
115+
</Optimizations>
116+
</CodeGeneration>
117+
<Linking>
118+
<Debugging>
119+
<RunWithoutDebug Value="True"/>
120+
<DebugInfoType Value="dsDwarf3"/>
121+
<UseExternalDbgSyms Value="True"/>
122+
</Debugging>
123+
</Linking>
124+
</CompilerOptions>
125+
</Item5>
99126
</BuildModes>
100127
<PublishOptions>
101128
<Version Value="2"/>

0 commit comments

Comments
 (0)