Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Programmcode schneller machen


Marco D. - Di 08.03.05 18:31
Titel: Programmcode schneller machen
Kann mir jemand ein ganz allgemein ein paar tips geben, wie man seinen programmcode so umgestalten kann, sodass das Programm schneller wird?


Moderiert von user profile iconChristian S.: Topic aus Sonstiges verschoben am Di 08.03.2005 um 18:05


Harry Hunt - Di 08.03.05 18:42

Das hängt ganz von dem Programm ab, das du schneller machen möchtest.
In der Regel geht es darum, deine Algorithmen so zu optimieren, dass weniger Schritte durchgeführt werden müssen bzw. dass jeder einzelne Schritt weniger zeitintensiv ist. Wie man das macht lässt sich schlecht veralgemeinern.


matze.de - Di 08.03.05 19:04

Oder dinge durch Asm, Bytecode oder Maschinencode ersetzen.

mfg matze


zemy - Di 08.03.05 19:39

*g* brauche ich wenigstens kein Topic aufmachen :D

Wo kann ich zu letzteren (Asm, Bytecode oder Maschinencode) EINSTEIGERtutorials finden?? (habe so ungefähr das Level, wo ich zumindest weiß, was Assembler ist ^^)

MfG Zemy


MisterBum - Di 08.03.05 20:03

Dann vergess es zu lernen. Ich habe 2 Jahre für gebraucht und bekomm es immer noch nicht richtig hin...


matze.de - Di 08.03.05 20:48

user profile iconMisterBum hat folgendes geschrieben:
Dann vergess es zu lernen. Ich habe 2 Jahre für gebraucht und bekomm es immer noch nicht richtig hin...


das liegt aber dann an dir ;D Warum sollte er es nicht lernen? Ich empfele die GE-PACKT Reihe, dort gibt es auch ein Buch zu Asm. Google ienfach mal.

mfg matze.de


Harry Hunt - Di 08.03.05 23:23

Assembler muss überhaupt nicht schwer sein, wenn man die Ziele nicht gleich wahnsinnig hoch steckt.
About.com hat ein ziemlich gutes (englisches) Tutorial zum Thema:
http://delphi.about.com/library/bluc/text/uc052501a.htm


Delete - Mi 09.03.05 00:26

user profile iconMisterBum hat folgendes geschrieben:
Dann vergess es zu lernen. Ich habe 2 Jahre für gebraucht und bekomm es immer noch nicht richtig hin...

Hm, da hab ich andere Erfahrungen gemacht. Vor einigen Jahren oder eher gesagt vor fast einem Jahrzehnt habe ich angefangen zu programmieren mit QBasic. Dann bin ich umgestiegen auf Visual Basic 6, hab Pascal und Delphi gelernt und ganz wenig mit C gemacht. Vor kurzem habe ich ein Werksauftrag bekommen, bei dem ich einen Algorithmus mit Assembler (den Inline-Assembler von Delphi) Geschwindigkeitsoptimieren soll. Da ich vorher noch nie mit Assembler gearbeitet habe, hab ich mich in das Thema in meiner Freizeit (ich bin nebenbei noch Schüler) eingelesen und nach 1 bis 2 Wochen habe ich das nötige Wissen gehabt um meine Aufgabe zu beginnen.

Mein Tipp: Besorg dir das Buch "Das Assembler-Buch - Grundlagen und Hochsprachenoptimierung". Für den Einstieg ist es optimal. Dieses Buch hat mir mehr geholfen als die anderen Tutorials, die es im Internet gab. Wenn du dann den Einstieg gefunden hast, kannst du dir auch Assembler GE-PACKT (aus der GE-PACKT-Reihe) kaufen. Dieses ist allerdings nur als Referenz gedacht. Für den Anfang ist es nicht gedacht.

Vielleicht hilft auch diese Seite weiter:
http://ivs.cs.uni-magdeburg.de/bs/lehre/sose99/bs1/seminare/assembler.shtml


Lossy eX - Mi 09.03.05 10:04

Für meinen Geschmack wird Assembler ein wenig überbewertet. Es ist nicht das Maß aller Dinge! Klar kann man damit seinen Code richtig gut optimieren etc. Aber dazu muss man schon sehr sehr genau wissen was man tut. Und das kann man nicht von heute auf morgen erlernen. Wenn man nicht genau weiß was man tut kann man damit seinen Code nicht nur langsamer sondern auch gefährlich für seine Umwelt gestalten. Delphi optimiert den resultierenden Code ja indem er zum Beispiel If Abfragen und die Schleifenzählung umstellt. Bei reinem Assembler kann Delphi das allerdings nicht mehr. Also wäre ich vorsichtig mit den Aussagen, dass Assembler das Heilmittel für alle Performanceprobleme ist.

Ich persönlich denke, dass wenn man seinen Code sinnvoll durchdenkt und kritische Stellen entsprechend optimiert, kann man auch sehr schnelle Anwendungen schreiben. Und zwar ohne, dass man sich auf die Prozessorebene begeben muss. Bisher hat sich aber noch niemand über meine Programme beschwert, weil sie zu langsam gewesen wären. Und die die mich kennen wissen, dass ich sehr auf die Geschwindigkeit achte. Aber bevor mich jemand falsch versteht. Ich meine damit jetzt nicht, dass man nicht wissen sollte wie ein Prozessor aufgebaut ist und wie er arbeitet. Das ist notwendiges Wissen um schnelle Programme schreiben zu können. Ich finde nur den Schritt das man sein Programm auf Maschinenebene schreibt ein wenig übertrieben. In Delphi gibt es reichlich Befehle die direkt so in Assembler übersetzt werden. Im Endeffekt ist das reine Geschmackssache und ist jedem selbst überlassen.

Aber sonst kann ich das nur noch mal bestätigen. Optimierungen lassen sich selten verpauschalisieren.
So ein paar Dinge sollte man aber dennoch immer beachten.
- Keine unnötigen Berechnungen. Lieber ein mal berechnen und dann in Variablen ablegen anstelle von 10 - 20 Mal das Selbe zu berechnen. Macht den Code dann auch übersichtlicher. ;-)
- Records oder große Datentypen lieber Lieber als Var, Const oder Pointer an Methoden übergeben (und zurückgebe), da Delphi die Variablen intern sonst kopieren muss.
- Überprüfen ob man diverse Operationen nicht viel einfacher darstellen kann. Also Bitweise Operationen anstelle von Berechnungen etc.


jasocul - Mi 09.03.05 10:19

Sparsam mit Try-Except umgehen. Lieber die möglichen Fehler schon vorher analysieren und abfangen. In Schleifen sind Try-Except der Geschwindigkeitstod.
Ich muss Lossy-Ex recht geben. Ich habe auch schon die eine oder andere Kleinigkeit mit asm gemacht. Das war aber nicht für die Geschwindigkeitzsoptimierung, sondern weil z.B. in Turbo-Pascal die UpCase-Funktion keine Umlaute berücksichtigt. Das habe ich dann eben umprogrammiert.
Sicher gibt es auch zeitkritische Echtzeit-Routinen. Aber hier gehts imho mehr ums Grundsätzliche.


Gausi - Mi 09.03.05 11:19

Ich muss mich meinen beiden Vorrednern anschließen. Gerade als Informatiker ist es mir erstmal völlig egal, ob eine Berechnung nun 5 Minuten, oder 10 dauert. Das ist nur ein konstanter Faktor, und der reguliert sich im nächsten Jahr durch nen schnelleren Rechner raus.
Viel wichtiger ist es, das Problem, das man durch ein Programm lösen möchte, vorher genau analysiert und eine schnellen Algorithmus dafür entwickelt.

Beispiel: Sortieren: Man kann mit Bubblesort sortieren. Klappt wunderbar, und bei kleinen Arrays ist auch nichts dagegen zu sagen. Bei langen Listen ist das aber zu langsam. Bei 100 Elementen werden ca. 100*100/2 Vergleiche durchgeführt, bei 10.000 dann 10.000*10.000/2 usw.
Quicksort ist da in der Regel besser. Da werden bei 1024 Elementen nur ungefähr 10*1024 Vergleiche benötigt. Das ist ungefähr 50mal schneller als Bubblesort!

Das man durch geschickte Programmierung am Ende den Code noch ein paar Hundertstel schneller macht, ist eine schöne Sache, bringt aber längst nicht soviel, wie die Verwendung eines geeigneten Verfahrens, das sich hinter dem Code verbirgt.

Wenn du ein Formel1-Rennen gewinnen willst, dann nimmst du auch keinen VW Golf, legst den tiefer, lackierst ihn mit nem speziall-windschnittigen Lack und tankst V100-Shell-Power, sondern du baust dir einen Rennwagen. Und dann geht es an die Feinoptimierung.


Amiga-Fan - Mi 09.03.05 11:42

Indizes benutzen;) Man kann die auch über den Quälcode einsetzen...

Bei Querys immer die Filter-Eigenschaft benutzen statt ständig die Query neu zu öffnen... allerdings funzt die filter-Eigenschaft offenbar nicht mit Interbase, er meldete mir da immer Fehler...

die Komponenten von Delphi z. B. Treeview sind teilweise etwas langsam, da wird es von Drittanbietern schnellere Komponenten geben...

Wenn die Verzögerungen deutlich sind kann man die Stellen gut übers Debugging herausfinden.
Ansonsten gibt es noch spezielle Programme dafür, sogenannte Profiler. Bis jetzt musste ich die aber noch nicht benutzen...

SQL-Abfragen optimieren. Die Felder die die Daten m meisten einschränken in der Where-Klausel an erster Stelle einfügen. Speziell für SQL-Optimierung gibt es auch Bücher...

Textsuche und in-Textsuche (%) über Datenbanken möglichst vermeiden, da langsam

etwas was speziell auch Speicherverbrauch betrifft: Hat ein Programm viele Formulare nicht alle direkt bei Programmstart erstellen sondern erst wenn sie geöffnet werden sollen und anschließend wieder freigeben. Dürfte das Programm auch schneller machen aber kaum merklich...


Motzi - Mi 09.03.05 11:50

Muss mich Gausi anschließen - viel ausschlaggebender für die Geschwindigkeit ist es, die richtigen Algorithmen korrekt umzusetzen oder die passenden Datenstrukturen zu verwenden, und nicht seinen Code mit feinstem ASM zu optimieren..!


Gausi - Mi 09.03.05 12:01

Wobei mir bei nochmaligem Überlegen eine Einschränkung eingefallen ist. Für "kleine" Programme kann man auch ruhig dreckige, langsame Standard-Algos verwenden. Oftmals sind nämlich die High-Speed Algorithmen für kleine Datenmengen nicht schneller, sondern sogar langsamer als einfache. Der Geschwindigkeitsvorteil wird erst bei größeren Datenmengen spürbar.

Um beim Beispiel mit dem Auto zu bleiben: Wenn du nur schnell mit dem Auto zum Baumarkt fahren willst, dann lohnt sich der Formel-1-Rennwagen nicht, weil da der Motor ne halbe Stunde vorgewärmt werden muss, und die Reifen müssen erstmal lieb gekuschelt werden, damit sie nicht kaputtgehen, und man muss sich in feuerfeste Klamotten reinzwängen usw. Da ist dann ein Golf doch etwas schneller. Ganz abgesehen davon, dass ein Golf einen etwas größeren Kofferraum hat :roll:


Delete - Mi 09.03.05 12:05

Ich schließe mich den Vorredner an. Versuche so viel wie möglich deinen Quellcode mit der Hochsprache zu optimieren, in den du einen effizienten Algorithmus benutzt. Allerdings ist an manchen Stellen Assembler sinnvoll. Nämlich da, wo man auf mehrere Werte dieseblen Operationen anwenden, also besonders, wenn man mit Feldern arbeitet. Denn die Prozessoren besitzen Erweiterungen wie MMX und SSE, die Delphi nicht unterstützt. Diese muss man dann halt in Assembler schreiben. Mit MMX und SSE kann man mehrere Werte auf einmal berechnen.
Ein Beispiel:
Man addiert zu allen Werten eines Array of Byte x. In Delphi würde man eine Schleife schreiben, die jeden einzelnen Wert des Arrays durchläuft. Mit MMX kann man immer 8 Werte auf einmal berechnen. Also könnte der Quellcode mit Assembler 8 mal so schnell sein.


Lossy eX - Mi 09.03.05 12:17

@Gausi: Bist ein leichter Autofan? ;-)

Bei den Optimierungen muss man aber auch ganz klar sehen wo es sich lohnt Optimierungen zu betreiben und wo nicht.
Im kommerziellen Einsatz an besonders Zeitkritischen Stellen da sollte man schon alles einfließen lassen was man hat. Und dann sollte man auch noch abwägen wie häufig ein Stück Code aufgerufen wird. Es bringt absolut nichts einen Code um 50 oder 100 ms schneller zu machen, wenn er nur einmal zur ganzen Laufzeit aufegrufen wird. Wenn der Code allerdings 1 Mio Mal aufgerufen wird dann sollte man sich schon ein paar Gedanken machen. Aber auch dann sollte der Zeit und Nutzenfaktor keine astronomischen Werte annehmen. Also 3 Wochen zu programmieren um noch mal 1 ms raus zu holen bringt kaum etwas. Außer an besonders zeitkritischen Stellen.


delfiphan - Mi 09.03.05 12:38

Da gibt's eigentlich nur eins: Profiling! Es gibt Programme, die dir genau angeben, auf welcher Zeile sich dein Programm am längsten aufhält. Dort musst du dann optimieren.


zemy - Mi 09.03.05 19:17

Das ganze Prog in ASM zu schreiben hatte ich auch nicht vor. Nur probier ich mich gerne an diversen Berrechnungsprogrammen (polyalphabetische Verschlüsselung, astronomische Berrechnungen über "Bruteforcen", etc.) Die können dann mal etwas länger laufen. Gerade da ist etwas optimierung nicht unbedingt falsch :D Ich sehe mir die Links mal an, mal sehen, ob das Kosten-Nutzen-Verhältniss stimmt ^^

MfG Zemy


Alni - So 13.03.05 17:00

Grundsätzlich hat Gausi Recht. Zu erst sollte man nach einem schnelleren Algorithmus suchen. Wenn das nichts hilft zuerst den Delphi-Code optimieren bevor man Assembler einbaut.

Zu Codeoptimierung in Delphi hier ein paar Links:
http://web.archive.org/web/20030605130659/www.optimalcode.com/index.htm (sehr zu empfehlen)
http://www.azillionmonkeys.com/qed/optimize.htm
http://www.drbob42.com/delphi/perform.htm

Diese Seiten enthalten einige Hinweise mit denen man auf Recht einfache Weise zum Teil noch viel herausholen kann


retnyg - So 13.03.05 17:05

auf der website von user profile iconmael gibts zu dem thema auch ein nettes tutorial, in deutsch
hier der genaue link http://mh-nexus.de/optimizingger.htm