Hallo allerseits,
ich habe - da ich krank geschrieben bin - heute aus Langweile das "Sieb des Eratosthenes" zunächst mit Lazarus, dann mit c# (Visual Studio 2008) und zuletzt mit Delphi 2007 umgesetzt.
In allen 3 Varianten verwende ich denselben Algorithmus, nur bei den Laufzeiten muss Delphi 2007 eine Niederlage einstecken:
Das ermitteln aller Primzahlen von 1 bis 100000 dauert bei der Lazarus-Anwendung 156 ms, bei der c#-Variante 63 ms, und bei Delphi 2007 skandalöse 8019 ms (!).
Kann mir das einer plausibel erklären, weshalb Lazarus so extrem performanter ist als Delphi?
Schön ist das Ergebnis von der c#-Umsetzung, das zeigt doch mal, das .net nicht langsamer ist als nativer Code...
Hier die Quellen:
1. Delphi und Lazarus:
======================
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
Var
Zahlen: Array of Boolean;
Beginn, Dauer, i, j: Integer;
PrimZahlen: TStringList;
begin
Primzahlen := TStringList.Create;
ProgressBar1.Max := SpinEdit1.Value;
Beginn := GetTickCount;
SetLength(Zahlen, SpinEdit1.Value);
i := 2;
while (i*i) < SpinEdit1.Value do
begin
j := i * i;
repeat
Zahlen[j-1] := True;
inc(j, i);
until j > SpinEdit1.Value;
ProgressBar1.Position := i * i;
Application.ProcessMessages;
inc(i);
end;
for i := 0 to SpinEdit1.Value -1 do
if not Zahlen[i] then
PrimZahlen.Add(IntToStr(i+1));
Memo1.Lines.Assign(PrimZahlen);
Dauer := GetTickCount - Beginn;
Label2.Caption := IntToStr(Dauer);
FreeAndNil(PrimZahlen);
end;
2. C#
=====
Code:
private void buttonSieb_Click(object sender, EventArgs e)
{
textBox1.Text = "";
StringBuilder primZahlen = new StringBuilder();
progressBar1.Value = 0;
progressBar1.Maximum = (int)numericUpDown1.Value;
int beginn = System.Environment.TickCount;
bool[] zahlen = new bool[(int)numericUpDown1.Value];
for (int i = 0; i < (int)numericUpDown1.Value - 1; i++)
{
zahlen[i] = false;
}
for (int i = 2; (i * i) < numericUpDown1.Value; i++)
{
for (int j = i * i; j < numericUpDown1.Value; j = j + i)
{
zahlen[j - 1] = true;
}
progressBar1.Value = i * i;
Application.DoEvents();
}
for (int i = 1; i < (int)numericUpDown1.Value; i++)
{
if (!zahlen[i - 1])
primZahlen.Append(i.ToString() + System.Environment.NewLine);
}
int dauer = System.Environment.TickCount - beginn;
labelDauer.Text = dauer.ToString();
textBox1.Text = primZahlen.ToString();
}
Gruß,
Patrick
//Edit: Titel angepasst, da das Nadelör (SpinEdit1.Value) gefunden wurde