Ich möchte mit einem Programm alle Primzahlen von 0 und bis zu einer eingegebenen Grenze herausfinden.
An sich klappt das auch ganz gut. Allerdings habe ich dass Problem, dass ich bei einem Durchgang von 0 bis 1.000.000.000 bspw. knapp 1 GB Arbeitsspeicher benötige. Theoretisch könnte ich ja 1/8 des benötigten Rams sparen, wenn ich für jede Boolean-Variable nur ein Bit benötigen würde. (
Imho benötigt eine Boolsche Variable bei Delphi 1 Byte.) Allerdings fällt mir dazu keine schnelle Lösung ein. Lediglich:
Delphi-Quellcode:
var
i: Byte;
...
if i and 1 shl x
...
was aber nicht allzu schnell sein dürfte.
Zusätzlich zu diesem Arbeitsspeicher-Problem würden mich auch noch Vorschläge für Verbesserungen der Geschwindigkeit interessieren. Gern auch in Assambler (Wenn es 'ne ausführliche Erklärung dabei gibt
)
Jetzt aber erstmal mein Quelltext (Ich habe ihn mal ein wenig kommentiert):
Delphi-Quellcode:
program Primzahlengenerator;
{$APPTYPE CONSOLE}
uses
Classes, Windows;
var
IsPrim: array of Boolean;
j, k, Max, HalfMax: Int64;
s: String;
F: TMemoryStream;
Time, Time2: Cardinal;
begin
Writeln('Bitte geben sie eine obere Grenze ein: ');
Readln(Max);
Writeln('Bitte geben sie eine Datei an,' +
' in der die Primzahlen gespeichert werden sollen:');
Readln(s);
Time := GetTickCount;
SetLength(IsPrim, Max);
// Länge der Arrays festlegen
j := 2;
while j < Max do
// Vorerst alle Zahlen als Primzahlen markieren
begin
IsPrim[j] := True;
Inc(j);
end;
HalfMax := Max div 2;
// Die Hälfte der Grenze speichern, so dass diese folgend nicht mehr
// errechnet werden muss
F := TMemoryStream.Create;
j := 2;
while j <= HalfMax do
// Die halbe Liste durchgehen
begin
if IsPrim[j] then
begin
F.Write(j, 4);
// Zahl im MemoryStream schreiben
k := j shl 1;
// Startwert ist das doppelte der aktuellen Zahl (j)
while k < Max do
begin
IsPrim[k] := False;
// Alle Vielfachen der Zahl (j) als Nicht-Prim markieren
Inc(k, j);
// k auf das nächste Vielfache setzen
end;
end;
Inc(j);
end;
// Die restlichen Primzahlen in den Stream schreiben
while j < Max do
begin
if IsPrim[j] then
F.Write(j, 4);
Inc(j);
end;
F.SaveToFile(S);
F.Free;
// Benötigte Zeit ausgeben
Time2 := GetTickCount;
Time := Time2 - Time;
Write(Time div 60000);
Write(' Minuten ');
Write((Time mod 60000) div 1000);
Write(' Sekunden ');
Write((Time mod 60000) mod 1000);
Writeln(' Millisekunden');
end.
PS: Es ist mir klar, dass es schon einige Beiträge zu Primzahlen in der
DP gibt, mir geht es jedoch direkt um die Optimierung meines Programms.
EDIT:
Über Bewertungen meines Programmes würde ich mich im übrigen auch freuen.