Optimierung / Diskussion :-)

  • Hi folks,

    ich bin gerade über diesen Thread gestolpert. Obwohl er als gelöst markiert ist, möchte ich mir gern eine Ergänzung erlauben.

    Um n Leerzeichen zu generieren, wurde folgende Lösung vorgeschlagen, die auch soweit korrekt und universell verwendbar ist:

    Code
    $str = ""
    $n = 5
    For $k = 0 To $n
       $str = $str & " "
    Next

    Hier mal eine Alternative für Geschwindigkeitsfanatiker: ;)

    Man kann anhand der Aufgabenstellung davon ausgehen, dass die zu generierenden Leerzeichenketten sicherlich nicht kilometerlange Ausmaße annehmen werden. Wenn man als worst case-Szenario mal eine maximale Leerzeichenkette von 10, 100 oder auch 1000 annimmt, dann kann man diese als Konstante definieren (hier: $Dummy). Dann könnte man auch folgenden Code zur Leerzeichengenerierung verwenden:

    Code
    $Dummy = "                    "
    $n = 5
    $str = StringLeft($Dummy, $n)

    Vorteil der zweiten Lösung: Die Ausführungsgeschwindigkeit ist schneller. Man kann das mit den AutoIt-Funktionen TimerInit() und TimerDiff() nachprüfen. Auf meinem etwas älteren Schätzchen ergibt sich nach mehreren Durchläufen im Mittel:

    Lösung 1 -> For-Next mit 10.000 Durchläufen -> ca. 7 sec.
    Lösung 2 -> For-Next mit 10.000 Durchläufen -> ca. 0,5 sec.

    Der Geschwindigkeitsgewinn liegt darin begründet, dass die zweite Version ein memcpy-Befehl auf CPU-Ebene (Assembler bzw. Binärcode) ist (Kopieren im Arbeitsspeicher), während bei der ersten Lösung die CPU richtig arbeiten muss. Dazu benötigt sie zusätzliche CPU-Register, muss if-Abfragen (conditional branches) behandeln und daher im Code hin und her springen sowie die Register pushen und pullen. Das kostet eben alles Zeit.

    Wenn jetzt jemand meint, ich spinne, weil der Geschwindigkeitsgewinn bei obiger Aufgabenstellung völlig Banane ist, muss ich sagen: Stimmt! :D Wenn aber mal jemand vorhat, zeitkritische Dinge in einem Echtzeitsystem zu programmieren, sind obige Überlegungen oftmals vonnöten. Der zweiten Lösung wird in solchen und anderen ähnlich gelagerten Fällen dann der unbedingte Vorzug gewährt. ;)

    Man muss aber auch ins Kalkül ziehen, dass die zweite Lösung statischen Arbeitsspeicher (im obigen Fall für die Leerzeichenkette) benötigt. Man muss also immer abwägen.

    Ich wollte die beiden Möglichkeiten auch einfach nur mal gegenüberstellen. ;)

    Einmal editiert, zuletzt von Flex (9. März 2007 um 14:37)

    • Offizieller Beitrag

    Hi,

    dasselbe Prinzip gilt auch für z.B. Arraynutzung. Es ist schneller ein Array mit 1000 Einträgen anzulegen und dann z.B. die ersten 200 zu belegen und den Rest abzuschneiden, als ein Array mit einem Eintrag anzulegen und dann ArrayAdd zu nutzen, da das Array jedes mal neu dimensioniert werden muss.

    So long,

    Mega

  • Ja, das stimmt! Noch jemand, der sich mit den Internas auskennt. ;)

    Ich glaube aber, dass bei der Verwendung der oben beschriebenen Optimierungen bei AutoIt der "gefühlte Geschwindigkeitszuwachs" im Gesamtscript nicht nennenswert ist.

    In Zeiten von VisualBasic & Co und schnelle Rechner macht sich über sowas sowieso keiner mehr großartige Gedanken. Wenn es nicht schnell genug läuft, kauft man sich eben einen schnelleren PC. ;)

    • Offizieller Beitrag

    Hi!

    Ich gehöre auch zu den Menschen, denen es auffällt, wenn eine Software einfach gefühlt schnell ist. Das sind Optimierungen, die vielleicht nur einen kleinen Geschwindigkeitsfaktor bringen, aber oft die gefühlte Geschwindigkeit schön steigern. Bei AutoIt ist das aufgrund der verhältnismäßig mäßigen Performance durchaus eine Sache, die man sich überlegen sollte...

    peethebee

  • Zitat

    Original von FlexIch glaube aber, dass bei der Verwendung der oben beschriebenen Optimierungen bei AutoIt der "gefühlte Geschwindigkeitszuwachs" im Gesamtscript nicht nennenswert ist.

    Oh doch der ist schon sehr nennenswert.

    Hab dir mal ein kleines Skript gebastelt welches dir die Unterschiede verdeutlicht:

    [autoit]

    #include <Array.au3>

    [/autoit][autoit][/autoit][autoit]

    Dim $Zeit[3]

    [/autoit][autoit][/autoit][autoit]

    $Time = TimerInit()
    For $t = 1 To 20
    Dim $Array[1]

    For $i = 1 To 200
    $Array[0] += 1
    ReDim $Array[Ubound($Array) + 1]
    $Array[Ubound($Array) - 1] = $i
    Next
    Next
    $Zeit[0] = TimerDiff($Time) / 20

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $Time = TimerInit()
    For $t = 1 To 20
    Dim $Array[1000]

    For $i = 1 To 200
    $Array[0] += 1
    $Array[$i] = $i
    Next
    ReDim $Array[$i + 1]

    Next
    $Zeit[1] = TimerDiff($Time) / 20

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $Time = TimerInit()
    For $t = 1 To 20
    Dim $Array[1]

    For $i = 1 To 200
    $Array[0] += 1
    _ArrayAdd($Array, $i)
    Next
    Next
    $Zeit[2] = TimerDiff($Time) / 20

    [/autoit][autoit][/autoit][autoit]

    MsgBox(64, 'Speed-Vergleich', 'einmaliges ReDim: ' & Round($Zeit[1], 2) & 'ms' & @CRLF _
    & 'permanentes ReDim: ' & Round($Zeit[0], 2) & 'ms' & @CRLF _
    & '_ArrayAdd: ' & Round($Zeit[2], 2) & 'ms' & @CRLF & @CRLF _
    & 'Verhältnis: 1:' & Round($Zeit[0] / $Zeit[1]) & ':' & Round($Zeit[2] / $Zeit[1]))

    [/autoit]

    Und wenn du das gemacht hast setz mal statt "200" "2000" ein....

    Während ArrayAdd dabei bei mir 5s braucht ist das Skript ohne das permanente ReDim schon nach 65ms fertig....

    Und das nenne ich durchaus "nennenswert"... ;)

    Edit: kleinen Bug gefixt welcher das Ergebnis verfälschte.

    Einmal editiert, zuletzt von AspirinJunkie (16. März 2007 um 18:50)

  • Hi AspirinJunkie,

    ich musste über Dein Posting ein wenig schmunzeln. ;)

    Irgendwie habe ich den Eindruck, dass Du mein Posting vom 09.03.2007, 12:06 nicht intensiv genug gelesen hast. Ich habe doch selbst eine von mehreren Optimierungen vorgestellt, die grundsätzlich möglich sind. Im obigen Fall auch mit Benchmark-Ergebnissen. Komisch, dass Du mir jetzt erklärst, ich solle doch mal Dein Beispiel mit verschiedenen Parametern testen. ;)

    Ich darf vorsichtig anmerken, dass ich bereits in Assembler programmiert habe, als es noch gar nicht solchen Kram wie VB o.ä. im Entferntesten gab; das sollte einem Kenner der Szene bei meinem o.g. Posting aufgefallen sein. Gerade wenn man sich schon mal auf der Low Level-Ebene bewegt hat, kennt man noch mehr Tricks als meine und Deine o. g. Optimierungsmöglichkeiten, weil man die Zusammenhänge auf CPU-Ebene versteht. Du hast mir also nichts Neues demonstriert. ;)

    Inwieweit sich solche Optimierungen in einer High Level-Programmiersprache auswirken, muss im Einzelfall analysiert werden. Heute ist meistens schnelle Programmierung gefragt als Codeoptimierungen, die im Endeffekt nicht viel bringen und nur Entwicklungszeitaufwand kosten (-> teuer!).

    Was nennenswert ist, muss man immer im Gesamtzusammenhang sehen. Dies möchte ich auch gern gegenüber Mega erwähnen. Klar kann man sich etwas auf verschiedene Weisen zusammenkonstruieren und dann mit genügend vielen Schleifenwiederholungen die Unterschiede deutlich machen. Habe ich ja oben selbst getan. Wenn man aber bedenkt, dass niemand ein Array einfach mal so 2000 Mal hintereinander initialisiert oder eine Leerzeichenkette 20000 Mal an einem Stück generiert - außer er ist reif für die Klapse :D -, dann ist der Geschwindigkeitsunterschied einer Optimierung wie oben nicht nennenswert.

    Das heißt im Klartext: Wenn man bei einem Script den Code an einer Stelle optimiert, an der das Script sich eh nicht lange aufhält, dann ist eine solche Optimierung nur unter dem sportlichen Aspekt zu sehen.

    Ich kann übrigens auch ganz ohne Arrays auskommen, wenn ich Pointer verwenden würde und die Programmiersprache diese kennt. Pointer-Arithmetik ist deutlich schneller als lahmarschige Array-Operationen. ;)

    Jetzt bist Du wieder dran. ;)

    • Offizieller Beitrag

    Hi,

    ich glaube wir sind alle einer Meinung. :klatschen:

    Das Problem ist nur, dass nicht alle den Erfahrungsschatz von Flex vorweisen können. Darausfolgt, dass nicht alle dieses grundlegende Verständnis haben.

    Deshalb hilft es, solche Bsp. zu erstellen um zu verdeutlichen, dass es zwar mehrere Lösungen für bestimmte Probleme gibt, aber es trotzdem gute und weniger gute Varianten gibt.

    Flex, wie soll man denn sonst solche Erfahrungen aufbauen?

    So long,

    Mega

  • @Flex

    Kann es sein das du hier was ganz schön in den falschen Hals bekommen hast?
    Du wirkst irgendwie ziemlich angegriffen und beleidigt.
    Kann ich ehrlich gesagt nicht nachvollziehen deine Reaktion.

    Der einzige Grund für mein Posting in dieser Form (zur Veranschaulichung) war zu verhindern das Leute die diesen Thread lesen zu dem Schluss kommen das es zwar ganz schön ist effektiv zu programmieren aber man es im Grunde sowieso nicht merkt.

    Das es bei geringen Array-Größen keine nennenswerten Vorteile bringt ist klar.
    Aber deswegen sollte man es nicht einfach lassen seine Programme so effektiv wie möglich gestalten zu wollen.
    Lieber die Leute ein bisschen dazu anspornen - dazu war mein Beispiel gedacht.
    Das ich das nun gerade in der Du-Form verfasst und dabei dich angesprochen habe hätte ich mir wohl scheinbar vorher überlegen sollen... [Blockierte Grafik: http://img185.imageshack.us/img185/9279/mdakp6.gif]

    Und das dieser Fall auch gar nicht mal so realitätsfern ist habe ich auch noch zufällig gerade heute erlebt wo ich mit 2D-Arrays arbeiten musste welche bis zu 3000 Werte enthalten (EDBS-geografische Punktdateien auswerten).
    Dort machte sich die Sache schon deutlich bemerkbar.

    Also keep cool - hab ganz bestimmt nicht an deinen Fähigkeiten gezweifelt. ;)

    Ach und nach 2 Semestern Rechnerarchitektur mit DLX-Programmierung und Pipelining-Optimierung würde ich durchaus behaupten das ich beim Thema Low-Level-Hintergrundwissen ebenfalls nicht auf der Wurstbrühe daher geschwommen komme....
    Das heißt aber nicht das ich nicht noch sehr viel zu lernen habe - hab vielleicht gerade mal 0,1% der Programmierwelt erfasst. ;)

    Aber ein was könntest du mir vielleicht noch erklären:
    Wie kann man mit Pointern komplett auf Arrays verzichten?
    Meinst du das du die Werte direkt anhand der Registeradresse hintereinander in das Register schreibst?
    Aber genau das wäre ja meiner Meinung nach nichts weiter als ein Array.
    Also kleines Verständnisproblem bei mir denn bisher war ich immer der Meinung das ein Array nichts weiter als ein Pointer auf die einzelnen Elemente darstellt. Also der Anfangsadresse und jeweils die einzelnen Elemente in den sizeof-Abständen.

    Einmal editiert, zuletzt von AspirinJunkie (17. März 2007 um 00:26)

  • Hi AspirinJunkie und Mega,

    ich kann mich immer noch nicht des Eindrucks erwehren, dass ihr etwas falsch verstanden habt.

    Ich hatte einfach auf actio eine reactio gemacht. Das kann man auch ganz leicht anhand der vorherigen Postings nachvollziehen.

    Weder wollte ich jemanden angreifen, noch wollte ich überheblich wirken. Ich darf aber anmerken, dass Zitieren mit Autorangabe sehr wohl als direkt angesprochen verstanden werden muss, zumal dann auch noch die direkte Anrede folgte. Wenn dies nicht beabsichtigt ist, muss man eben anders formulieren. Dann gibt es auch keine Kommunikationsprobleme zwischen Quelle und Senke infolge Informationsverfälschung. ;)

    Außerdem bin ich gar nicht so doll, wie Mega unüberhörbar sarkastisch meinte. Man beachte einfach nur meinen Status, der steht bei meinen popeligen 17 Postings erst bei Jungspund. Es steht mir daher auch gar nicht zu, Euch niedermachen zu wollen.

    Also genau, keep cool. ;)

    Ich muss ehrlich gestehen, dass ich jetzt um 2:45 Uhr keine große Lust verspüre, noch über Pointer und Arrays zu philosophieren. Ich glaube auch nicht, dass dies in einem AutoIt-Forum sinnvoll wäre.

    Zu guter Letzt bitte ich Smileys korrekt zu deuten, dann sollten Missverständnisse erst gar nicht entstehen. ;)

    Und wenn gar nichts fruchtet, dann bitte ich Euch beide um Entschuldigung für mein flegelhaftes Verhalten. Ist das ok? ;)


    EDIT: Ich sehe, dass ich erst 13 Postings verfasst habe und nciht 17, wie fälschlich angenommen. Ich bin also noch ein Greenhorn. ;)

    2 Mal editiert, zuletzt von Flex (17. März 2007 um 02:50)

  • Ja genau ein Post-Counter ist DAS Maß für Erfahrung, Cleverness, IQ und Potenz schlechthin. [Blockierte Grafik: http://www.runescape.ex.lv/bildes/posti.gif]

    Du hast schon Recht - ich habe dich ja bewusst mit diesem Satz zitiert.
    Eben weil er den Eindruck hinterlassen könnte das man sich Code-Optimierungen getrost schenken könnte.
    Hatte aber doch nichts mit deinen restlichen Äußerungen zu tun (gerade mit deinen oberen Posts hattest du ja die Diskussion erst ins Rollen gebracht ;-))

    Also gib ruhig (das ist keine Erlaubnis sondern eine Bitte) weiterhin Möglichkeiten wie man auch mit AutoIt seinen Code optimieren kann (egal ob es sich nun bemerkbar macht oder nicht).
    Gerade Leute wie ich, die darauf viel Wert legen auf dem Gebiet Wissen zu sammeln, profitieren davon.

    Und damit jetzt nicht wieder irgendwelche Missverständnisse auftauchen mach ich mal den Anfang: [Blockierte Grafik: http://www.diegotorres.com.ar/mensajeitor/foro/caritas/110103_sorry_prv1.gif]

    P.S: Die Ironie verteilt über deinen gesamten letzten Post hab ich durchaus wahr genommen - den "unüberhörbaren Sarkasmus" bei Meger (wohlgemerkt: nicht "Mega" ;-)) allerdings nicht....

    • Offizieller Beitrag

    Hi,

    hui da habt ihr ja noch fleißig diskutiert. :klatschen:

    Also, ich habe wirklich keinen Sarkasmus an den Tag gelegt. Alles was ich geschrieben habe, meinte ich auch so. Ich bin lediglich ein Projektleiter in der IT-Branche, der zum Spaß ein bißchen Autoitskripte schreibt.

    Ich habe wirklich nicht die tiefste Ahnung vom Programmieren, aber denke ich für einen nicht täglich Programmierer ein relativ gutes Verständnis.
    Deshalb würde ich mich freuen, wenn ihr beide euer Wissen teilt. Vielleicht nicht alles in diesem Thread :rofl_devil:

    Evtl. sollten wir auch einen Developer-Bereich eröffnen, in dem Leute wir ihr solche Dinge erläutern könnt. (auch, weil siehe Eng-Forum)

    Umgang mit DLLs, Pointern, Guter Programmierstil usw.

    Also, bis demnächst - ggf. kann ja jeder von anderen profitieren.

    So long,

    Mega

  • Ähm bevor hier falsche Schlüsse gezogen werden:

    Ich bin KEIN Profi in der Programmierung, KEIN Profi für Rechnerarchitektur und auch ansonsten nur ein ganz kleines Licht.

    Ich hatte vor etwa 2 Jahren etwa angefangen mit AutoIt Silent-Skripte zu schreiben für unattended Installationen.
    Das hatte mit Programmierung ja erstmal nicht viel zu tun.
    Nacheinander hab ich dann anhand wachsender Aufgaben ersteinmal Schritt für Schritt selbst erkannt wie Programmierung funktioniert.
    Bis vor 2 Jahren wusste ich noch nicht einmal wofür eine For-Schleife z.B. gut ist.
    Bis ich halt einmal soetwas brauchte.
    Aber bis heute hab ich mir das halt alles autodidaktisch erschlossen.

    Erst jetzt im Studium hab erst so richtig tiefe Einblicke gewonnen (und das nicht zu knapp).
    Zumindestens von dem was intern in einem Prozessor exakt abgeht hab ich mittlerweile ein, meiner Meinung nach, vernünftiges Wissen.
    Zwar hatten wir auch andere Programmiersprachen relativ intensiv behandelt (erst JAVA und jetzt momentan C) aber dort ging es weniger um die Sprache selbst sondern eher um Themen wie Algorithmen und deren Optimierung (daher wahrscheinlich mein Optimierungswahn ;-)).

    Folglich ist AutoIt immernoch die einzige Sprache mit der ich momentan meine meisten Ziele programmiertechnisch lösen kann weil mir einfach in den anderen Sprachen die Übung und das Wissen fehlt. (zumindestens bei C bin ich aufgrund der mir gefallenden Sprache (z.B. wegen Pointern ;-)) durchaus gewillt dies zu ändern).
    Aber auch in AutoIt lern ich immer wieder viele Dinge hinzu.


    Also kurzum - ich hab hier eher von euch zu lernen als andersrum.


    Und wenn jetzt einer ganz laut ruft: [Blockierte Grafik: http://digilander.libero.it/le.faccine/faccinea/cartelli/statici/1241.gif]
    dann muss ich ihm durchaus dabei Recht geben... ;)

  • Zitat

    Original von th.meger
    na dann bleibt nur noch zu hoffen, das Flex noch ein seinen Beitrag schreibt

    [list=1]
    [*]Huch, der Thread ist ja SplitMiddle() and MoveBottom() worden! Da ist mein nun erstes Posting ja sehr bezugskräftig.
    [*]Ich bin auch nur ein ziemlich kleines Licht.
    [*]Mega hat wiklich keine Ahnung vom Programmieren. Das sehe ich anhand der Inhalte seiner nunmehr 1.403 Postings.
    [*]Ich hoffe, AspirinJunkie brauchte Ersteres nicht wirklich.
    [*]Spam ist eigentlich anders definiert.
    [/list=1]Für alle Punkte [1..5] gilt zusätzlich: Es fehlt absichtlich jeweils genau ein entsprechender Smiley. Der muss jeweils hinzugedacht werden.

    Das war mein Beitrag!

    :party4:

    ;)

    4 Mal editiert, zuletzt von Flex (18. März 2007 um 22:38)