vgl. StringRegExp() StringReplace() StringInStr()

  • Hallo zusammen,

    neulich gab es eine interessante Diskussion in der Shoutbox, die ich an dieser Stelle noch einmal aufgreifen wollte.
    Es ging um die "Suchgeschwindigkeit" diverser AutoIt-eigener Funktionen.

    Dazu hatte AspirinJunkie ein kleines Testscript gepostet, welches StringRegExp() (und auch Replace) als wesentlich schneller als die "nativen" Funktionen StringReplace() und auch Stringinstr() auswiesen.

    Spoiler anzeigen

    Allerdings sieht das mit den "alten" AutoItversionen wiederum völlig anders aus!
    String nach zeichen durchsuchen

    vgl heute:

    Spoiler anzeigen


    Ich will ja niemandem auf den Schlips treten, aber wenn eine Funktion in egal welcher Bibliothek hochoptimiert ist, dann die Suchfunktion von Strings in Strings!

    Dass PCRE hochoptimiert und im Lauf der Jahre ggf. sogar multithreaded doppelt bis dreimal so schnell wird, akzeptiere ich, aber dass eine 6 Jahre alte SUCHFUNKTION aus einer Bibliothek Faktor 3-4 SCHNELLER sein soll als eine aktuelle Funktion, kann mir wirklich keiner mehr erzählen....
    Für mich sieht das so aus, als ob, nachdem in einigen Threads im EN-Forum das "elitäre" RegEx mit "simplen" Stringfunktionen geschwindigkeitsmäßig an die Wand gespielt wurde, dieses "Sakrileg" in den neueren AutoIt-Versionen einfach "korrigiert" wurde.

    Wer möchte, kann die Funktionen gerne unter 3.3.6 oder 3.3.8 testen und sich bei den Stringfunktionen gegenüber der aktuellen Version 3.3.12. um Faktor 3-4 an Geschwindigkeitszuwachs wundern.

    Da wird AutoIt-Usern im Jahre 2015 ein Golf II als "neu" verkauft und alles freut sich!

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    2 Mal editiert, zuletzt von Andy (30. Mai 2015 um 22:49)

    • Offizieller Beitrag

    Für mich sieht das so aus, als ob, nachdem in einigen Threads im EN-Forum das "elitäre" RegEx mit "simplen" Stringfunktionen geschwindigkeitsmäßig an die Wand gespielt wurde, dieses "Sakrileg" in den neueren AutoIt-Versionen einfach "korrigiert" wurde.

    Das klingt sehr wahrscheinlich. RegEx in AutoIt ist nicht sonderlich schnell, dass ist sicherlich dem Jos sofort aufgefallen als er seine AutoIt-Tools in Lua geschrieben hat und somit vergleichen konnte. Dort sind schon die Stringoperationen mit Pattern nutzbar (was ich sehr praktisch finde) und zusätzlich kann man dann noch mit einer RegEx-Library arbeiten, beides affenartig schnell. Und da es syntaktisch durchaus vorteilhaft ist mit Pattern zu arbeiten, musste wohl ein Grund konstruiert werden eine RegEx-Nutzung zum Goldstatus zu erheben. Und sei es darum all jenen, die mit RegEx nicht so warm werden klar zu machen (völlig zu unrecht) , sie seien keinesfalls elitär?
    Ich verwende viel RegEx, das ist einfach dem Umstand geschuldet, dass ich viel komplexe Textverarbeitung mache (auch in Lua und Python) und somit kein Weg an RegEx vorbeiführt. Da fängt man dann schon an in RegEx zu denken und übersieht durchaus, dass manchmal eine simple native Stringoperation den Zweck auch erfüllt.

  • RegEx ist für "Viel-Text-Bearbeiter" die ultimative und schnelle Waffe, da gibt es gar keine Diskussion! Und ein Geschwindigkeitsgewinn dieser Engine hilft ALLEN Anwendern weltweit, egal in welcher Sprache sie arbeiten!

    Sehr wohl sei aber die Frage erlaubt, wieso gerade bei einer "langsamen" Scriptsprache bei Simpelst-Funktionen noch absichtlich gebremst wird?!
    Den ersten Reflex bei einem derartigen Vorkommen, nämlich ein Ticket zu schreiben, unterdrücke ich mittlerweile...

    Die logische Konsequenz, und das ist jetzt kein Witz, ist doch, sämtliche "einfachen" Stringfunktionen komplett zu entfernen und den User darauf hinzuweisen, diese durch RegEx-Konstrukte zu ersetzen!
    Den Aufschrei der Nicht-"Goldstatus-User" (hehe, DER hat mir gefallen ^^) kann ich mir vorstellen 8o
    Da man das vermeiden will, kommt bei solchen Threads aus dem Lager der "Goldstatus-User" der wohlgemeinte Rat, RegEx zu benutzen, das sei "professioneller" und nebenbei auch noch 10x schneller (s.o. AspirinJunkies Beispielscript).

    Einige (teilweise zugegebenermaßen profilneurotische) TOP-Entwickler abzusägen und durch wesentlich profilneurotischere Leute (mit deutlich weniger Skill) zu ersetzen hat noch keinem Produkt gutgetan....
    Sonst würden die TOP-TEN der Hard/Softwareindustie immer noch in ihrer Garage hocken und an ihren Prototypen rumbasteln... :S:/X/||


    //EDIT

    Da wird einmal erwähnt das mal man mit den Funktionen die Anzahl zählen kann und schon wird alles zerlegt und gebenchmarkt

    Stell dir vor, einige alte Scripte von dir, welche intensiv Stringfunktionen mit größeren Textdateien nutzten, sind nun, nur weil sie mit der neuesten AutoIt-Version compiliert werden, jetzt extrem langsamer...
    Alle Anwender deines Scriptes warten jetzt länger, das summiert sich bei der tägl. Arbeit auf Stunden...
    Du erklärst das deinem Chef damit, dass du eine "neue" Compilerversion benutzt und der fragt dich, ob du noch alle Tassen im Schrank hast, KEIN Entwickler würde sein Produkt künstlich schlechter machen!
    Also setzt du dich hin und schreibst ALLE je von dir geschriebenen Scripte mit Stringfunktionen in die RegEx-Variante um! Was deutlichen Zeitaufwand bedeutet aber natürlich auch wesentlich "professioneller" ist! Aber billiger, als alle Anwender der Scripte warten zu lassen, ist es auch! DAS wiederum kapiert jeder Chef sofort, dein Job ist wieder mal eine Woche länger gesichert...
    Ein HOCH auf die AutoIt-Entwickler, mit jeder neuen Version werden Jobs in der IT sicherer, Arbeit für Scripter ist mit jeder neuen Version GARANTIERT!!! :thumbup:

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    3 Mal editiert, zuletzt von Andy (31. Mai 2015 um 10:53)

    • Offizieller Beitrag

    @Andy, vermutlich müssen wir für 3.3.12 die nativen Stringfunktionen per FASM einbinden um den Speed von 3.3.8 wieder zu erreichen.
    Oder wir nutzen Stringoperationen über LuaEmbedded :whistling: . Lua-Skripte im Textbereich sind etwa >10 mal schneller als in AutoIt. Rechnen wird den Portierungszeitaufwand raus, könnte etwa die Hälfte stehen bleiben -- immer noch schneller als mit der aktuellen Version. :rofl:

  • @Andy, vermutlich müssen wir für 3.3.12 die nativen Stringfunktionen per FASM einbinden um den Speed von 3.3.8 wieder zu erreichen.

    Mich hat es ja schon in den Fingern gejuckt 8o

    Aber wesentlich einfacher ist, einfach bei der 3.3.8 zu bleiben....
    Sämtliches Objektgedöns wickele ich sowieso direkt in VBA ab, alternativ funktioniert die "alte" Excel-UDF immer noch!
    Meinen programmiertechnisch eher unbedarften Kollegen einen RegEx-Kurs nahezubringen dürfte auf totales Unverständnis stossen! Die haben das in ihrem ganzen Leben noch nicht gebraucht, und werden das auch in Zukunft nicht brauchen!

    Ternäre Operatoren?! "Alter, wer soll denn DIESE Programmzeile verstehen? Schreib das gefälligst LESBAR als IF/THEN/ELSE, das kapieren auch die Programmierer unserer Produktionsmaschinen sofort auf Anhieb!"

    "Und was soll überhaupt dieses AUTOIT? Statt die diversen Branchensoftware "fernzusteuern", schreib/lese doch per VBA direkt aus deren Datenbank, das machst du doch aus Excel auch!!"

    Manchmal bin ich echt froh, KEIN Programmierer zu sein.... ;(


  • Stell dir vor, einige alte Scripte von dir, welche intensiv Stringfunktionen mit größeren Textdateien nutzten, sind nun, nur weil sie mit der neuesten AutoIt-Version compiliert werden, jetzt extrem langsamer...

    Alle Anwender deines Scriptes warten jetzt länger, das summiert sich bei der tägl. Arbeit auf Stunden...
    Du erklärst das deinem Chef damit, dass du eine "neue" Compilerversion benutzt und der fragt dich, ob du noch alle Tassen im Schrank hast, KEIN Entwickler würde sein Produkt künstlich schlechter machen!
    Also setzt du dich hin und schreibst ALLE je von dir geschriebenen Scripte mit Stringfunktionen in die RegEx-Variante um! Was deutlichen Zeitaufwand bedeutet aber natürlich auch wesentlich "professioneller" ist! Aber billiger, als alle Anwender der Scripte warten zu lassen, ist es auch! DAS wiederum kapiert jeder Chef sofort, dein Job ist wieder mal eine Woche länger gesichert...
    Ein HOCH auf die AutoIt-Entwickler, mit jeder neuen Version werden Jobs in der IT sicherer, Arbeit für Scripter ist mit jeder neuen Version GARANTIERT!!! :thumbup:

    Wenn ich eine Software programmieren müsste die beruflich Verwendung finden soll greife ich (persönlich zumindest) nicht auf AutoIt zurück.
    Mich würde mich eher wundern warum die Dauer künstlich hochgesetzt wird, hat ja eigentlich keinen Nutzen.

  • Was da genau passiert ist weiß keiner der keine Einsicht in den Code hat. Es heißt immer: Je mehr eine Funktion kann, desto langsamer ist sie im Vergleich zu einer Funktion die nur eine bestimmte Sache kann.
    In AutoIt kann man aktuell mit einem Taschenmesser besser Schießen als mit der Magnum.

  • Ich habs mal verglichen (Plot.pdf) für das Beispiel des Zählens eines Substrings.
    Im Vergleich zu 3.3.8.1 sind die RegEx-Funktionen tatsächlich auf einmal schneller geworden als StringReplace.
    Wenn man sich die Grafiken aber mal anschaut liegt das aber nicht daran, das StringReplace wesentlich langsamer geworden ist, sondern dararan dass die RegEx-Funktionen massiv an Performance hinzugewonnen haben.
    Der StringReplace-Graph bleibt nahezu konstant - nur die Regex-Graphen wandern nun nach unten.
    Tatsächlich ist StringReplace etwas langsamer geworden (ca. Faktor x1,2) - aber eine künstliche Verschlechterung wird kaum der Grund hierfür sein.

    Heißt zusammengefasst: Niemand hat hier die Standard-String-Funktionen künstlich verschlechtert weil er einer Verschwörung der progressiven Programmierertechniken gegenüber den "guten alten" Techniken angehört.
    Die Regex-Funktionen sind halt massiv schneller geworden (etwa um den Faktor x3) - nicht mehr und nicht weniger.
    Das schadet keinem einzigen AutoIt-User. Im Gegenteil - es profitieren alle davon.

    Der Fairness halber sollte man bei Zeitvergleichen bei RegEx-Funktionen dazu sagen, dass AutoIt einmal verwendete Pattern zwischenspeichert, so dass sie bei nochmaliger Verwendung nicht nochmal kompiliert werden müssen. Da der Zeitvergleich hier aber auf Mehrfachmessungen beruht, erscheinen die RegEx-Funktionen daher schneller als sie eigentlich sind.
    Ob dies bei 3.3.8.1 auch schon so war weiß ich nicht. Es könnte daher eine Ursache für den massiven Performancesprung sein.
    Ein anderer könnte der native 16Bit-Modus der PCRE-Engine sein, welcher in Version 3.3.10.0 aktiviert wurde.

    Was bleibt ist die Frage warum die "nativen" Stringfunktionen bisher nicht stark optimiert wurden.
    Auch wenn die PCRE-Engine wahnsinnig viel aus einem RegEx-Pattern rausholen kann, sollte eine vernünftig optimierte StringReplace diese dennoch schlagen können.
    Das ist bisher anscheinend versäumt wurden. Aber das war dann schon immer so und ist nicht erst seit den letzten Versionen künstlich verschlechtert worden.

    4 Mal editiert, zuletzt von AspirinJunkie (31. Mai 2015 um 14:25)

  • @AspirinJunkie,
    die Grafik sagt mir eigentlich nur, dass auf deinem System aktuell der von dir geposte Code im Bezug der AutoIt-Versionen in etwa gleich schnell ist.
    Dass die RegEx-Engine zugelegt hat ist unzweifelhaft für uns alle ein Vorteil, auf meinen Rechnern (alle AMD) teilweise wesentlich mehr als der von dir angegebene Faktor 1.2!

    Was ich allerdings nicht verstehe, sind deine Angaben zum StringInstr() und Stringreplace().

    Ich habe das "damals" in diesem Thread vorgestellte Script (Suche von NEEDLE in a HAYSTACK) nochmals auf aktueller AutoIt-Version laufen lassen.
    Lassen wir aussen vor, dass für alle Algorithmen eine in etwa lineare Suchzeit abhängig von der Größe des Haystacks gilt und beschränken uns nur auf den 52MB großen String:

    Suchzeiten in Millisekunden: damals (9.Februar 2010) = AutoIt 3.3.6 (Release 3.3.8.1 erst im Januar 2012!) heute=3.3.12

    Code
    Stringlänge     Suchzeit   Boyer-Moore        StringInstr            FindBytes              StringRegExp        Stringreplace
    damals     52428651             766.900541             3617.06166             535.991306             1134.43077             577.359971  
    heute      52428651             653.176145             9291.22775             468.556555             240.314610             5136.25052


    Deine Boyer/Moore-Umsetzung liegt als dll vor, genau wie Findbytes aus der prospeed.dll. Ich gehe jetzt einfach mal davon aus, dass diese beiden Funktionen auf meinem Rechner damals und heute gleich schnell laufen (ich weiss, du bist ein ganz genauer, aber hier geht es nicht um +-10% )
    StringRegExp hat Faktor 4,7 zugelegt, da ziehe ich wirklich den Hut!
    Jetzt solltest du allerdings erklären können, wieso StringInstr ca. 2.5x langsamer läuft, und StringReplace ca. 9x langsamer....
    Und das ist mir nicht nur im Beispielscript aufgefallen, sondern in einigen meiner beruflich genutzten Anwendungen.

    //EDIT
    Mal ausser Konkurrenz StringInstr() und StringReplace() mit gesetztem casesense-flag, da tue ich mir kein RegEx an :thumbup:

    Code
    Stringlänge     Suchzeit   Boyer-Moore        StringInstr            FindBytes              StringRegExp        Stringreplace
              52428651             721.892732             336.473134             473.657176             188.530235             589.024543

    und wen es interessiert, hier gibt es eine feine Dokumentation zu Agner Fog´s für C++ optimierten Bibliotheken:
    http://www.agner.org/optimize/
    dort sind auch die Downloadlinks zu finden.

    @AspirinJunkie, mit Zugriff auf den neuen INTEL-Compiler und die dort angehängten Bibliotheken und Möglichkeiten der Verwendung externer Hardware (Grafikkarten) durch einfache #pragma<blablub> kannst du wahrscheinlich darüber nur lachen...jaja, ich bin zugegebenermaßen ein kleines bisschen neidisch :saint:


    //EDIT2
    Da die RegEx-Engine wirklich rasend schnell ist, stellt sich mir die Frage, wieso man nicht die Stringfunktionen nur als Wrapper für einen StringRegExp-Aufruf nimmt....damit werden diese gleich schnell und das Umschreiben der Funktionen gestaltet sich als Einzeiler...

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    6 Mal editiert, zuletzt von Andy (31. Mai 2015 um 15:34) aus folgendem Grund: der Code lief damals unter 3.3.6 , die 3.3.8.1 wurde erst 2012 released!

  • Ich habe dein Skript mal abgewandelt und auf 3.3.12.0 und 3.3.8.1 laufen lassen:

    Spoiler anzeigen

    Beim StringReplace habe ich den Casesense-Parameter wieder auf 0 gestellt, da in der 3.3.8.1 noch ein Bug drin war (Ticket 2311).
    Ansonsten ist der Vergleich der Selbe.

    Im Ergebnis (>>Plot2.pdf<<) kann ich hier von 3.3.8.1 zu 3.3.12.0 bei mir keine Verschlechterung der StringInStr um den Faktor 2,5x und beim StringReplace um den Faktor 9x feststellen.
    Die StringInStr ist bei mir über die Versionen konstant und die die StringReplace gerade mal um den Faktor 1,1x langsamer geworden.

    Ich denke daher jemand Drittes müsste sich das Verhalten mal anschauen, da wir unsere Ergebnisse jeweils gegenüber nicht reproduzieren können.

    Hier daher mein Testskript für meinen ersten Test weiter oben:

    Spoiler anzeigen
  • Habs mal laufen lassen (1 Kern durchgängig ausgelastet)

    Spoiler anzeigen


    N|StringReplace-CS|StringReplace-CI|StringRegExp-CS|StringRegExp-CI|StringRegExpReplace-CS|StringRegExpReplace-CI
    56353|0.188236123229141|5.03922025111201|0.0366557632009387|0.213200351408631|0.0440495598206334|0.18729194594186
    112706|0.372041991946032|10.0745583825325|0.0755673120100857|0.41607950484753|0.0856716654353711|0.371785994914393
    169059|0.742304690441499|15.3400813785815|0.11248354420507|0.621347233798749|0.298544559678398|0.735564804243085
    225412|0.857571985612364|21.3335879248911|0.158001367927668|0.853783229544105|0.394464320187836|0.890652825559707
    281765|1.23163936583813|26.0371267977392|0.336982445530608|1.1690405622779|0.496875179762622|1.27849435195255
    338118|1.49034079392647|31.3234682390232|0.368270667404705|1.43669549795589|0.604408535377279|1.45482063538317
    394471|1.69343112047061|36.9875912860676|0.465312251626409|1.77134887245354|0.648619033693383|1.86534711024742
    450824|1.97012906165643|46.3308367097334|0.545869999888566|1.85291253846355|0.74129512211209|1.92816964230589
    507177|2.14228446439439|46.8767800863112|0.554568970679195|2.09026367721638|0.835084220696164|2.30643742730266
    563530|2.46951301232912|51.8608424229848|0.633487242764395|2.30299447257233|0.926121967225754|2.44837066924551
    619883|2.65833675750278|57.2870157402034|0.668336302731582|2.5833279540493|1.01774715317079|2.83003881885446
    676236|2.82202845422065|62.4208291533034|0.721648102866233|2.94556584529768|1.18790152005014|3.16871619898017
    732589|3.15008865026619|67.5796022769882|0.777086518865024|3.04483873341503|1.22408745340478|3.25278863590024
    788942|3.40796586178475|72.9089872038916|0.85427715322868|3.25604560653807|1.29235476266558|3.4812154326025
    845295|3.64405403571444|77.6443398720381|0.899765856543017|3.71012675374473|1.45457281705829|4.1999266852302
    901648|4.19817563464425|82.3398891663361|0.956199108668531|3.68404826276901|1.46801748770938|3.89614933280648
    958001|4.06996949199867|87.8569765666341|1.03277690165342|3.91579630642007|1.63520499653637|4.19898104420012
    1014354|4.43285555160776|93.2924643426937|1.09501019073531|4.15777510488281|1.7546337721524|4.41809807566621
    1070707|4.54307390995711|97.9241351290873|1.18008608126069|4.51370954456321|1.80200828165456|4.94122458740055
    1127060|4.99522490242748|105.502219494264|1.22137689659918|4.75681637272686|1.95075761568581|4.94224857552711
    1183413|5.17187623972419|109.079799762803|1.28804990128386|4.89064760522808|1.95749050493624|5.47873804104847
    1239766|5.27762141880649|114.059561105973|1.34159176411035|5.25704126528256|2.07381020192678|5.43175505641823
    1296119|5.69013637413635|118.979100402337|1.43712215967529|5.47807295072117|2.19701923079819|5.91142322001499
    1352472|5.96021324251563|124.371715520437|1.44058564892688|5.61457960318051|2.34497045643668|5.97643893672687
    1408825|6.26548970274528|128.617614523284|1.50413314736906|6.00749740012426|2.48430060556851|6.66458154574622
    1465178|6.72119130950742|134.070507261775|1.70347739053578|6.74537119720174|2.55467827691367|6.83094734777825
    1521531|6.63079639127653|140.880458550488|1.65507459043594|6.31619970298321|2.62459343261343|6.53463616174486
    1577884|6.79132158876318|145.397192732249|1.76147470123318|6.9906550757521|3.02640121050885|6.91996547525074


    Hradware steht in meiner Signatur

  • hmmm, da ist offensichtlich etwas oberfaul

    bitte mal das von mir verlinkte Script von "damals" durchlaufen lassen und die letzen Zeilen posten.
    Dann dort die casesense-flags setzen und die sicherheitshalber auch mal posten.

    Es macht nichts, wenn ihr die dll´s nicht habt, es geht sowieso nur um die AutoIt-Funktionen.
    Da zzt. mobil online und die dll´s nicht im Zugriff, poste ich das komplette Paket später noch mal...

    • Offizieller Beitrag

    Hier mal meine Ergebnis, man muss aber dazu sagen das das Flag 2 bei StringReplace in v. 3.3.8.1 nicht korrekt funktioniert!

    Edit: Flag 2 bringt in der v. 3.3.8.1, bei StringReplace, die gleichen Ergebnisse wie Flag 1. Arbeitet also case sensitive.

  • Ich hatte den obigen Post als Antwort auf AspirinJunkie bereits editiert.
    in 2010, als dieses Script geschrieben wurde, war imho die 3.3.6 aktuell und nicht die 3.3.8.1, die gab es erst 2012!!

    Habe eben mal nachgeschaut, in der Firma benutz(t)e ich tatsächlich auch die 3.3.6 8o . Das wird in dieser Woche dort mal ausprobiert!
    Vielleicht finde ich ja wirklich noch auf einer meiner alten Platten (liegen in der Bank im Tresor) die damals aktuelle Version .
    Und ein XP-Rechner steht noch komplett auf dem Speicher.
    Sehr misteriös....

    Ändert aber alles nichts daran, dass der Thread von "damals" vergleichbare Zahlen/Ergebnisse liefert.

    • Offizieller Beitrag

    3.3.6.1 hab ich auch noch!

    Brainfuck
    Stringlänge     StringInstr   StringRegExp    Stringreplace     Flag     Version
    
    
    52428651       7191.63656     459.650437      7276.70624          0      3.3.6.1
    52428651        299.095816    447.887331       478.197996         1      3.3.6.1
    52428651       4060.91742     387.314237       388.969682         2      3.3.6.1     (bei StringReplace fehlerhaft)
  • Bernds Ergebnisse decken sich weitgehend mit meinen.
    Auffällig ist lediglich das Verhalten von StringReplace bei Flag 2.
    Das hängt aber wahrscheinlich mit dem oben angesprochenen gefixtem Bug zusammen.

    in 2010, als dieses Script geschrieben wurde, war imho die 3.3.6 aktuell und nicht die 3.3.8.1, die gab es erst 2012!!

    Die Version 3.3.6.0 habe ich mal in meinen zweiten Vergleich mit hinzu genommen.
    Ergebnisse hier: >>Plot2.pdf<<