Ich habe mal versucht, x- Units in ein Programm einzubinden.
Beipielhaft mit l= 4.
Code: Alles auswählen
//Unit 1
unit p000001;
interface
procedure go;
implementation
procedure go();
Begin
writeln(1);
writeln(2);
writeln(3);
writeln(4);
End;
End.
// und das Programm:
program test;
uses
p000001,
p000002,
p000003,
p000004;
BEGIN
p000001.go;
p000002.go;
p000003.go;
p000004.go;
END.
Leider musste ich feststellen, dass Freepascal die Units nicht parallel compiliert.
Der große Vorteil ist der erheblich geringe Bedarf an Hauptspeicher während des kompilierens.
Code: Alles auswählen
{$MODE objFPC}
const
l = 1000;
StrLen = 7;
type
tStr7 = string[StrLen];
tNameLst = array[1..l] of tStr7;
procedure StringInc(var s:tStr7);// Spielerei ;-)
var
i : integer;
ch : pChar;
Begin
i := Length(s)-1;
ch := @s[1];
repeat
ch[i] := chr(Ord(ch[i])+1);
IF Ord(ch[i])<=Ord('9') then
BREAK
else
Begin
ch[i] := '0';
dec(i);
IF i < 1 then
BREAK;
end;
until false;
end;
procedure BuildUnit(var name:tStr7;ofs,cnt:integer);
var
f: Text;
Begin
Assign(f, name+'.pas');
Rewrite(f);
WriteLn(f, 'unit '+name+';',#13#10);
WriteLn(f, 'interface ',#13#10,' procedure go;',#13#10,'implementation');
WriteLn(f, ' procedure go();',#13#10,' Begin');
For cnt := cnt downto 1 do
Begin
writeln(f,' writeln(',ofs,');');
inc(ofs);
end;
WriteLn(f, ' End;',#13#10,'End.');
Close(f);
end;
procedure BuildProgram(NameLst:tNameLst);
var
f: Text;
i : integer;
begin
Assign(f, 'pascaltest.pas');
Rewrite(f);
WriteLn(f, 'program test;' + #13#10);
Writeln(f, 'uses');
for i := 1 to l-1 do
Writeln(f,' ',NameLst[i],',');
Writeln(f,' ',NameLst[l],';');
Writeln(f,'BEGIN');
for i := 1 to l do
Writeln(f,' ',NameLst[i],'.go;');
Writeln(f,'END.');
Close(f);
end;
procedure Button1Click;
var
name : tStr7;
NameLst : tNameLst;
i, j: LongInt;
begin
setlength(name,StrLen);
fillchar(name[1],StrLen,'0');
name[1] := 'p';
j := 1;
for i := 1 to l do
Begin
StringInc(name);
writeln(Name);
NameLst[i] := name;
BuildUnit(name,j,l);
inc(j,l);
end;
BuildProgram(NameLst);
end;
procedure Button2Click;
var
f: Text;
i, j: integer;
begin
Assign(f, 'ctest.c');
Rewrite(f);
WriteLn(f, '#include <stdio.h> ');
WriteLn(f, 'void Ausgabe(int i) {printf("%d\n", i);}',#13#10);
for i := 1 to l do begin
WriteLn(f, 'void p', i, '()');
WriteLn(f, '{');
for j := 1 to l do begin
WriteLn(f, ' Ausgabe(', l * (i-1) + j, ');');
end;
WriteLn(f, '};' + #13#10);
end;
WriteLn(f, 'int main()');
WriteLn(f, '{');
for i := 1 to l do begin
WriteLn(f, ' p', i, '();');
end;
WriteLn(f, '}');
Close(f);
end;
Begin
Button1Click;
// Button2Click;
end.
Erstellt 1000 Units p00001 bis p001000. Das geht relativ fix:
Code: Alles auswählen
...
p000999
p001000
real 0m2.113s
user 0m0.160s
sys 0m0.300s
Das Kompilieren dauert aber länger, es wird auch nur eine Unit nach der anderen kompiliert.
l=707 dauerte zuvor 36.? jetzt 40.6 Sekunden .
Aber jetzt kann ich auch l=1000 auf Linux 32-Bit testen
Code: Alles auswählen
...
Compiling p000999.pas
Compiling p001000.pas
Linking pascaltest
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
1011005 lines compiled, 94.10 sec
real 1m34.998s
user 1m30.347s
sys 0m3.053s
Aber nochmaliges kompilieren bei Änderung an einer Unit dauert nur 1,8 s, ohne Änderung 1,6 s.
Code: Alles auswählen
time fpc pascaltest.pas
Free Pascal Compiler version 2.6.4 [2014/03/03] for i386
Copyright (c) 1993-2014 by Florian Klaempfl and others
Target OS: Linux for i386
Compiling pascaltest.pas
Compiling p001000.pas
Linking pascaltest
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
3013 lines compiled, 1.8 sec
real 0m1.757s
user 0m0.843s
sys 0m0.250s
Man bräuchte ein Hilfsprogramm, was alle genutzten units rausfischt und dann parallel compiliert und erst zum Schluss alles zusammenführt.
Lazarus kann das wohl,
Gruß Horst
EDIT: Beim Text umkopiren entstehen merkwürdige Sätze.
Mal 4096 Units mit 4096 Zeilen erzeugt.->Die ausführbare Datei hat 688.163,980 Byte und funktioniert sogar.xterm ist so schnell...
Code: Alles auswählen
Compiling p004095.pas
Compiling p004096.pas
Linking pascaltest
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
16822277 lines compiled, 3724.0 sec
real 62m4.489s
user 53m58.993s
sys 0m51.983s
Ich gehe davon aus das ein i7 bei single Thread nicht wirklich viel schneller ist als ein i3 -4330 mit 3,5 Ghz.
EIne ntfs Festplatte ist sicher nicht optimal, aber die Dateien sind ja zum Teil in dem 8 Gb Hauptspeicher als Cache zu finden.
Edit2:
Nochmaliges Kompilieren dauerte 4min 20 Sekunden, also praktisch nur das linken.
Der maximale Speicherbedarf war dann 2649 Mb.