Autor Beitrag
Hochhaus
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 662
Erhaltene Danke: 8

Windows 7
Delphi XE2
BeitragVerfasst: Do 19.12.13 16:21 
Hallo allerseits !

in einem anderen Beitrag habe ich erwähnt, dass mathematische Ausdrücke unter Delphi 6PE schneller abgearbeitet werden als unter XE2. In der Beilage findet Ihr ein einfaches Primzahlenprogramm. Dies bearbeitet keine Arrays wie mein Quadratwurzelprogramm. Trotzdem ist es unter Delphi XE2 deutlich langsamer als unter Delphi 6 PE.

Das Proggi ist in der Beilage gepostet. Hier die Rechenschleife:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
  Zaehler := 3;
  I       := 3;

  While (I <= N) And Go Do Begin
    Application.ProcessMessages;
    Inc(I, 2);
    Stop.Enabled  := True;
    Clear.Enabled := False;

    Q        := 3;
    PrimZahl := True;
    Wurzel   := Trunc(Sqrt(I));

    While (Q <= Wurzel) Do Begin
      If (I Mod Q = 0Then Begin
        PrimZahl := False;
        Break;
      End;
      Inc(Q, 2);
    End;

    If PrimZahl Then Begin
      Str(I, PrimeNumber);
      Write(Fil, ' ':10-Length(PrimeNumber), PrimeNumber);
      Inc(Zaehler);
    End;

    If (Zaehler = 7Then Begin
      Writeln(Fil, '');
      Zaehler := 1;
    End;

  End;  {* While I <= N *}


Viel Spass beim Ausprobieren !

Hochhaus
Einloggen, um Attachments anzusehen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 19.12.13 16:34 
Ich schätze mal alleine das unoptimierte Write in die Datei dürfte rund ein Zehntel bis ein Achtel der Zeit brauchen.

Ich kann ja nachher einmal den generierten Assemblercode anschauen, Delphi 6 PE sollte ich noch in einer VM haben.

Für diesen Beitrag haben gedankt: Hochhaus
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Fr 20.12.13 11:09 
Es gibt auch einen Shortcut, der alle Compilerflags in den Code einfügt (Ich glaube Strg+O+O).
Es wäre praktisch wenn du das einmal in Delphi 6 machst, und dann nochmal mit XE2 compilierst. Nur um sicher zu gehen, dass es wirklich nicht an den Flags liegt ;-)

Für diesen Beitrag haben gedankt: Martok
Hochhaus Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 662
Erhaltene Danke: 8

Windows 7
Delphi XE2
BeitragVerfasst: Fr 20.12.13 12:15 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
Es gibt auch einen Shortcut, der alle Compilerflags in den Code einfügt (Ich glaube Strg+O+O).


Der Shortcut funktioniert nur unter Delphi XE2 - nicht aber unter Delphi 6 PE .

Hochhaus
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1321
Erhaltene Danke: 117

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Sa 21.12.13 08:25 
Der Shortcut hat schon unter TP7 funktioniert. Auch auch unter D7P klappts. Warum sollte das bei einer Version anders sein? Eventuell wurden die Flags nur in einer anderen Datei erzeugt als du erwartest?

€:
Warum machst du eigentlich immer wieder die gleichen Fehler und stellst dann immer wieder die gleiche Frage!? Application.ProcessMessages ist ein gewaltiger Zeitfresser, egal in welcher Delphiversion. Ich sehe da nirgendwo eine Ausgabe also was willst du damit? Zugriffe auf Dateien via Write(ln) sind auch nicht von der schnellsten Sorte. Schreibe die Ergebnisse in ein Array dessen länge du vorher festgelegt hast oder eine Stringliste (jaaa die ist auch lahm aber immernoch besser als Dateizugriffe).
Die beste Lösung wäre aber deine Verarbeitung in einen Thread auszulagern und die Daten an dein Hauptprogramm zur Anzeige via FiFo Liste zu übergeben. Dann könntest du sogar mit sovielen Threads arbeiten wie du Kerne in der CPU hast und diese optimaler nutzen.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
Hochhaus Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 662
Erhaltene Danke: 8

Windows 7
Delphi XE2
BeitragVerfasst: Sa 21.12.13 09:18 
user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
1) Der Shortcut hat schon unter TP7 funktioniert. Auch auch unter D7P klappts. Warum sollte das bei einer Version anders sein? Eventuell wurden die Flags nur in einer anderen Datei erzeugt als du erwartest?

€:
2) Warum machst du eigentlich immer wieder die gleichen Fehler und stellst dann immer wieder die gleiche Frage!? Application.ProcessMessages ist ein gewaltiger Zeitfresser,


1) Das stimmt. Die Ausgabe war in einer anderen Datei als erwartet.

2) Wenn man das Application.Processmessages auskommentiert, sieht man, dass es auf die Zeit keinen grösseren Einfluss hat resp. hatte.


Grüsse,


Hochhaus
Hochhaus Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 662
Erhaltene Danke: 8

Windows 7
Delphi XE2
BeitragVerfasst: So 22.12.13 12:49 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Ich schätze mal alleine das unoptimierte Write in die Datei dürfte rund ein Zehntel bis ein Achtel der Zeit brauchen.


Das stimmt genau. Ich habe den fraglichen Code auskommentiert - und dann die Zeit wieder gestoppt.

Hochhaus
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: So 22.12.13 14:05 
Ich würde das Write durch eine Speicherung in eine Stringliste ersetzen, siehe Code-Schnipsel:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
var
 ErgListe : TStringList;



 Ergliste := TStringlist.Create;
 While (I <= N) And Go Do Begin
    Application.ProcessMessages;
    Inc(I, 2);
    Stop.Enabled  := True;
    Clear.Enabled := False;

    Q        := 3;
    PrimZahl := True;
    Wurzel   := Trunc(Sqrt(I));

    While (Q <= Wurzel) Do Begin
      If (I Mod Q = 0Then Begin
        PrimZahl := False;
        Break;
      End;
      Inc(Q, 2);
    End;

    If PrimZahl Then Begin
      Ergliste.Add(IntToStr(I));
//      Inc(Zaehler);
    End;

//    If (Zaehler = 7) Then Begin
//      Writeln(Fil, '');
//      Zaehler := 1;
//    End;

  End;  {* While I <= N *}

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.

Für diesen Beitrag haben gedankt: Hochhaus
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 22.12.13 14:59 
Eine Stringliste ist zwar schneller, aber durch das IntToStr und die Vergrößerung der beiden Arrays in der TStringList ist es trotzdem nicht optimal. Besser ist z.B. ein Array mit Pointerzugriff, das möglichst selten in der Größe verändert wird.

Wobei gerade bei Primzahlen im vorliegenden Fall natürlich das langwierigste der Algorithmus selbst ist. Sprich als echtes Tool zur Ermittlung von Primzahlen ist das nicht gut geeignet. Aber ich vermute mal darum geht es gar nicht. Trotzdem ist es ein gutes Beispiel dafür, dass die Geschwindigkeit des erzeugten Codes nicht die Hauptrolle spielt, da ein besserer Algorithmus hier deutlich mehr herausholen würde als der beste Compiler es könnte.

Eine Beschleunigung in der vorliegenden Form wird wohl ansonsten nur Assembler direkt bringen. Und das wiederum ist dann nicht mehr für alle Plattformen sofort, sprich man müsste x86, x64 und ARM separat schreiben.

Für diesen Beitrag haben gedankt: Hochhaus
Hochhaus Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 662
Erhaltene Danke: 8

Windows 7
Delphi XE2
BeitragVerfasst: So 22.12.13 16:29 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
da ein besserer Algorithmus hier deutlich mehr herausholen würde als der beste Compiler es könnte.


Nur ist es schwierig, meinen Algorithmus noch deutlich zu verbessern. Ich teile ja nur bis zur Quadratwurzel der entsprechenden ungeraden Zahlen. Wenn man da noch etwas optimieren wollte, müsste man wahrscheinlich ein Sieb benützen.
Oder alles in Assembler schreiben ...


Hochhaus

P.S. Das Proggi in der vorliegenden Form ist schon relativ schnell: Alle Primzahlen bis zu einer Million in 0.2 sec.
inkl. Dateiausgabe. (auf einem Core2-Duo 2.83 GHz)