Dateiname aus Pfad extrahieren

    • Offizieller Beitrag

    Oh, mein Lieblingspattern (für StringRegExpReplace) zum extrahieren des Dateinamens aus einer Pfadangabe war immer:

    [autoit]

    $string = StringRegExpReplace($sPath, '.+\\(.+)', '$1')

    [/autoit]


    Jetzt musste ich feststellen, dass es eine viel schnellere Methode gibt:

    [autoit]


    $sPath = @AutoItExe
    $iTimer = TimerInit()
    $string = StringRegExpReplace($sPath, '.+\\(.+)', '$1')
    ConsoleWrite('Mit RegExpRep: ' & TimerDiff($iTimer) & @CR)
    $iTimer = TimerInit()
    $string = StringMid($sPath, StringInStr($sPath, '\', 2, -1) + 1)
    ConsoleWrite('Mit StringMid: ' & TimerDiff($iTimer) & @CR)

    [/autoit]


    Die StringMid/StringInStr-Version ist bei mir fast 4mal schneller. :whistling:
    Meistens spielt das ja keine so große Rolle, aber bei meinem aktuellen Projekt ist das schon entscheidend.

    Nur als kleinen Tip für "Optimierungswütige"! ;)

  • Bei mir gibt es sogar eine Methode welche noch einen Tick schneller ist (wenn es dir schon auf die Nachkommastellen ankommt).
    Das muss bei dir aber nicht zwangsläufig ebenso sein - teste es einfach mal selbst - bei mir war es die Variante per StringTrimLeft:

    Spoiler anzeigen
    [autoit]

    Global $iN = 100000
    Global $sPath = @AutoItExe

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

    $iTime = TimerInit()
    For $i = 1 To $iN
    $sAusgabe = StringRegExpReplace($sPath, '.+\\(.+)', '$1')
    Next
    $iTime = TimerDiff($iTime) / $iN
    ConsoleWrite("RegExpReplace: " & @TAB & Round($iTime,5) & "ms" & @TAB & $sAusgabe & @CRLF)

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

    $iTime = TimerInit()
    For $i = 1 To $iN
    $aTemp = StringRegExp($sPath, '([^\\]+)$',1)
    $sAusgabe = $aTemp[0]
    Next
    $iTime = TimerDiff($iTime) / $iN
    ConsoleWrite("RegExp: " & @TAB & Round($iTime,5) & "ms" & @TAB & $sAusgabe & @CRLF)

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

    $iTime = TimerInit()
    For $i = 1 To $iN
    $sAusgabe = StringMid($sPath, StringInStr($sPath, '\', 2, -1) + 1)
    Next
    $iTime = TimerDiff($iTime) / $iN
    ConsoleWrite("StringMid: " & @TAB & Round($iTime,5) & "ms" & @TAB & $sAusgabe & @CRLF)

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

    $iTime = TimerInit()
    For $i = 1 To $iN
    $aTemp = StringSplit($sPath, "\")
    $sAusgabe = $aTemp[$aTemp[0]]
    Next
    $iTime = TimerDiff($iTime) / $iN
    ConsoleWrite("StringSplit: " & @TAB & Round($iTime,5) & "ms" & @TAB & $sAusgabe & @CRLF)

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

    $iTime = TimerInit()
    For $i = 1 To $iN
    $sAusgabe = StringRight($sPath, StringLen($sPath) - StringInStr($sPath, '\', 2, -1))
    Next
    $iTime = TimerDiff($iTime) / $iN
    ConsoleWrite("StringRight: " & @TAB & Round($iTime,5) & "ms" & @TAB & $sAusgabe & @CRLF)

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

    $iTime = TimerInit()
    For $i = 1 To $iN
    $sAusgabe = StringTrimLeft($sPath, StringInStr($sPath, '\', 2, -1))
    Next
    $iTime = TimerDiff($iTime) / $iN
    ConsoleWrite("StringTrimLeft: " & Round($iTime,5) & "ms" & @TAB & $sAusgabe & @CRLF)

    [/autoit]
  • Mit CaseSensitive beim StringInStr ist es noch schneller:

    Spoiler anzeigen
    [autoit]

    Global $iN = 100000
    Global $sPath = @AutoItExe

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

    $iTime = TimerInit()
    For $i = 1 To $iN
    $sAusgabe = StringTrimLeft($sPath, StringInStr($sPath, '\', 0, -1))
    Next
    $iTime = TimerDiff($iTime) / $iN
    ConsoleWrite("StringTrimLeft + non-casesens : " & Round($iTime,5) & "ms" & @TAB & $sAusgabe & @CRLF)

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

    $iTime = TimerInit()
    For $i = 1 To $iN
    $sAusgabe = StringTrimLeft($sPath, StringInStr($sPath, '\', 2, -1))
    Next
    $iTime = TimerDiff($iTime) / $iN
    ConsoleWrite("StringTrimLeft + non-casesens/faster : " & Round($iTime,5) & "ms" & @TAB & $sAusgabe & @CRLF)

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

    $iTime = TimerInit()
    For $i = 1 To $iN
    $sAusgabe = StringTrimLeft($sPath, StringInStr($sPath, '\', 1, -1))
    Next
    $iTime = TimerDiff($iTime) / $iN
    ConsoleWrite("StringTrimLeft + casesens : " & Round($iTime,5) & "ms" & @TAB & $sAusgabe & @CRLF)

    [/autoit]
    • Offizieller Beitrag

    Ok, die StringTrimLeft ist auch bei mir die schnellste Variante. Allerdings wirklich nur ein Tick, aber egal, jede gesparte Millisekunde wird mitgenommen. :D
    Wobei ich das mit CaseSensitive nicht verstehe, denn in der Hilfe steht: "2 = not case sensitive, using a basic/faster comparison". Sollte dann nicht die "2" am schnellsten sein?! ?(

  • Ok, die StringTrimLeft ist auch bei mir die schnellste Variante. Allerdings wirklich nur ein Tick, aber egal, jede gesparte Millisekunde wird mitgenommen. :D
    Wobei ich das mit CaseSensitive nicht verstehe, denn in der Hilfe steht: "2 = not case sensitive, using a basic/faster comparison". Sollte dann nicht die "2" am schnellsten sein?! ?(

    nicht casesensitive ist immer langsamer als Casesensitive, da dann nicht 1:1 überprüft werden kann, sondern auch Varianten überprüft werden müssen. 2 ist nur schneller als 0, aber dafür nicht ganz so exakt.

  • Also wenns auf Zeitersparnis ankommt, dann verwende ich Frank Abbings prospeed.dll
    Komplett in Assembler geschrieben rockt die das Haus. Übrigens sind im Downloadpaket auch sehr ausführliche AutoIt-Beispiele und eine hammermäßige Demo dabei.
    Eigentlich gehts dort um allerlei Grafikbefehle, aber _FindBytes() kann man auch als stringinstr()-Ersatz verwenden.Mal ein Zeitvergleich:
    Finden eines "Strings" innerhalb einer Bitmap (1680x1050x3 Bytes) in der untersten Bildzeile, dauert mit stringinstr ca 300ms, mit FindBytes nur 10ms...
    Das witzige daran ist, daß lt Autor nur ein einfaches zeichenweises Vergleichen, also "durch den String rennen", verwendet wird, und nicht eine der sehr viel schnelleren Methoden wie z.B. das Boyer-Moore-Verfahren! Btw, auf der verlinkten Wikipedia-Seite ist auch ein C-Quellcode, wäre sehr schön, den mal als AutoIt-verwendbare *.dll zu haben ;) ***mal bittend zu Bernd rüberschiel :D ***

  • Ich will ja nicht meckern, aber konterkariert die Verwendung einer DLL nicht gerade den Ansatz von AutoIt, ohne jegliche externe Zutat genau das zu tun, was man erwartet?
    Und wenn's um Geschwindigkeit geht, sollte wohl jeder noch so dämliche Versuch in einer herkömmlichen Programmiersprache um Größenordnungen schneller sein, als der optimalst optimierte AutoIt-Code!

    Schuster, bleib bei deinen Leisten!

    Gruß Ashpool

    Zitat von mir

    Bin immer wieder erstaunt, wie begrenzt ein Horizont sein kann.

  • Hi,

    Zitat

    aber konterkariert die Verwendung einer DLL nicht gerade den Ansatz von AutoIt, ohne jegliche externe Zutat genau das zu tun, was man erwartet

    Wer hat dir den diese Weisheiten gepredigt? Wenn du jeden Tag mit dem Fahhrad zur Arbeit fährst und dort irgendwann eine tolle Maschine ausgemustert wird, schulst du dann um auf Fuhrunternehmer und kaufst eine Flotte von Sattelzügen um das Ding nach Hause zu bringen oder leihst du dir einfach mal kurz ´nen kleinen LKW?

    Ich behaupte, daß für über 99% alles anfallenden Aufgaben für die AutoIt-Anwender diese Scriptsprache schnell genug ist, und das sahnige Geheimnis ist einfach, daß man das letzte Prozent (wenn man es überhaupt mal braucht) sehr gut mit "externen" Mitteln bewältigen kann. Genau dafür ist DOM/COM und das uralte *.dll-Prinzip nämlich gemacht worden....

    Zitat

    Und wenn's um Geschwindigkeit geht, sollte wohl jeder noch so dämliche Versuch in einer herkömmlichen Programmiersprache um Größenordnungen schneller sein, als der optimalst optimierte AutoIt-Code!

    Als was bezeichnest du denn eine herkömmliche Programmiersprache? Ich vermute du meinst eine Sprache, bei der man den größten programmtechnischen Unfug verzapfen kann, dann den Source durch einen "optimierenden" (wirds hell^^?) Compiler jagt, welcher die unzulänglichkeiten des Coders wegbügelt, um anschließend eine 6,3MB große Datei zu haben, die nichts weiter macht als 2x am Tag Daten mit einem Server abzugleichen....über eine 10MBit-Leitung. Das Programm schiebt dabei Äonen von Wartezeiten zwischen den einzelnen IP-Paketen....wer so etwas unbedingt braucht, der muss sich allerdings eine der "herkömmlichen" Programmiersprachen aneignen, AutoIt ist dafür viel zu langsam und auch viel zu einfach!
    Einen 10-Zeiler schreiben, F7 drücken und die EXE in den Autostartordner schieben, dauert incl. GUI keine 5 Minuten, und es wird genau das gemacht was gemacht werden soll. Ja, ich bleibe bei meineM Leisten!
    Andy

    P.S. ja, ich freue mich schon auf den Inline-Assembler, kein Witz....

  • Wer hat dir den diese Weisheiten gepredigt? Wenn du jeden Tag mit dem Fahhrad zur Arbeit fährst und dort irgendwann eine tolle Maschine ausgemustert wird, schulst du dann um auf Fuhrunternehmer und kaufst eine Flotte von Sattelzügen um das Ding nach Hause zu bringen oder leihst du dir einfach mal kurz ´nen kleinen LKW?

    Darum geht es doch überhaupt nicht. AutoIt ist für mich ein Tool, um Abläufe mit möglichst geringem Aufwand zu automatisieren. Das Verwenden einer fremden Dll stellt für mich eine Abweichung von eben diesem Prinzip dar. Man muss mit den Aufrufkonventionen vertraut sein und man muss sicherstellen, dass die Dll auf den Rechnern des Anwenders installiert ist.
    Im Übrigen sind das keine Weisheiten, sondern es ist meine Meinung, die ich ja wohl noch vertreten darf.

    Einen 10-Zeiler schreiben, F7 drücken und die EXE in den Autostartordner schieben, dauert incl. GUI keine 5 Minuten, und es wird genau das gemacht was gemacht werden soll. Ja, ich bleibe bei meineM Leisten!

    Da muss ich mich wiederholen: Du musst sicherstellen, dass die Dll beim Anwender vorhanden ist. Und wenn dann dank Avira irgendein Teil deines Codes als Schädling eingestuft wird,
    bist du Nase. Da nützt dir auch ein einzelner Leisten nichts.

    Als was bezeichnest du denn eine herkömmliche Programmiersprache? Ich vermute du meinst eine Sprache, bei der man den größten programmtechnischen Unfug verzapfen kann

    Wollen wir sachlich bleiben?
    AutoIt ist keine Programmiersprache (und will es auch laut dem Willen des Entwicklers auch nicht sein), warum muss man sie zwanghaft aufblähen, um sich hinterher Gedanken über die Ausführungsgeschwindigkeit machen zu müssen?
    Herkömmmliche Programmiersprachen sind in meiner begrenzten Wahrnehmung: C(++,#), Object Pascal, Fortran und Lisp.
    Basic in allen seinen Ausprägungen ist in meinen Augen eine Krücke, die dem Behinderten den Weg ins normale Leben ebnen kann.
    Dann kommen die Skript-Sprachen, zu denen AutoIt gehört, die algorithmisch nur eingeschränkte Möglichkeiten bieten, die jedoch den Zugriff auf die GUI-Funktionen des Betriebssystems deutlich vereinfachen können.

    Aber warum muss man nun jedes Problem in AutoIt lösen können wollen/müssen?
    Aber ich finde es wirklich albern, eine Skriptsprache zu verwenden, und sich dann über Ausführungsgeschwindigkeiten im ms-Bereich zu unterhalten.
    Um hier irgendwelchen Flame-Wars zuvorzukommen, wird das mein letzter Beitrag in diesem Thread sein, sollte noch Mitteilungsbedarf bestehen, kann man mich ja über PN kontaktieren.

    Sorry for the bad atmosphere!

    P.S.: Assembler habe ich vor ca. 20 Jahren aufgegeben.
    Bitte nicht falsch verstehen, ich schätze dein Wissen und deine Arbeit für das Forum

    Gruß Ashpool

    Zitat von mir

    Bin immer wieder erstaunt, wie begrenzt ein Horizont sein kann.

  • Hey,

    hier gibt es aber viele, wie mich z.B., die mit Autoit angefangen haben und gar keine Hochsprache beherrschen.
    D.h. ein Projekt scheitert, da Autoit zu langsam ist oder man findet eine entsprechende .dll zum Auslagern.
    Darum ists doch super, dass Autoit die Möglichkeit dazu gibt und es viele Pro's gibt die entsprechende Anwendungen frei verfügbar machen.

    Es bleibt der einfache Aufbau mit Autoit und der Speed der .dll ;)
    Einziger Nachteil: Man muss eine entsprechende Datei zum Auslagern finden.

  • [...]und nicht eine der sehr viel schnelleren Methoden wie z.B. das Boyer-Moore-Verfahren! Btw, auf der verlinkten Wikipedia-Seite ist auch ein C-Quellcode, wäre sehr schön, den mal als AutoIt-verwendbare *.dll zu haben ;) ***mal bittend zu Bernd rüberschiel :D ***

    Ich heiße zwar nicht Bernd (eher wie du...) aber ich hab dir trotzdem mal den Code direkt 1:1 als DLL kompiliert (siehe Anhang).
    Vielleicht kannst du damit ja was anfangen.

    • Offizieller Beitrag

    Ich sehe AutoIt als Programmiersprache an. Ist letztendlich aber eine Definitionsfrage...
    Und warum sollte man nicht auch ein Script optimieren (im ms-Berech) dürfen? Wenn ein bestimmter Befehl einige tausend mal ausgeführt wird, dann machen sich auch Millisekunden bemerkbar.
    Ich habe auch kein Problem damit, zeitkritische Dinge in einer anderen Programmiersprache (z.B. mittels dll) einzubinden. Dem Anwender ist das sowas von egal, in welcher Sprache ein Programm geschrieben ist, solange das Programm genau das macht, was er davon erwartet.
    Und der Vorteil für mich ist einfach, dass ich in AutoIt schnell zu einem funktionierenden Programm komme. Meine Programme gebe ich meist als ZIP-Archiv an andere weiter. Da schaffen auch DAUs die "Installation". Für die Super-DAUs könnte man ja auch noch ein Installationsskript erstellen, das war aber bisher nicht nötig. :)

    Soll jeder sehen, wie er will. Ich mag AutoIt und ich freue mich, wenn ich ein Problem mit AutoIt lösen kann.
    Programmieren mit AutoIt ist ein Hobby von mir und da kommt es im wesentlichen darauf an, dass es Spass macht. :)

  • Hi Ashpool,
    ehrlich gesagt kann ich keine deiner Aussagen nachvollziehen, vor allem mit dem Hintergrund, da du offenbar genau weißt um was es geht.

    Zitat

    Das Verwenden einer fremden Dll ...

    Jedes Mal wenn du ein Programm(paket) mit hunderten einzelner Dateien installierst, befindet sich "fremder" Code auf deinem Rechner. Glaubst du, daß niemand sicher stellt, nachdem diese neue Installation komplett abgelaufen ist ob eine "wichtige" *.dll auch vorhanden ist?
    Ich vermute daß ein Großteil der User überhaupt nicht weiß was eine dll ist, wichtig ist, daß wenn man 2x ganz schnell mit dem Mauszeiger auf das lustige Symbol auf dem Desktop klickt, daß dann ein E-Mail-Programm gestartet wird! Und daß dieses Programm funktioniert...

    Zitat

    Du musst sicherstellen, dass die Dll beim Anwender vorhanden ist

    Ja, zieh doch mal den SYSTEM und SYSTEM32-Ordner von deinem Rechner, bin mal gespannt was dann überhaupt noch für Software bei dir läuft. Natürlich fängt jedes halbwegs programmierte Programm diesen Fehler ab, es wird erst garnicht starten....das ist also kein Argument.

    Zitat

    Und wenn dann dank Avira irgendein Teil deines Codes als Schädling eingestuft wird,
    bist du Nase

    Die Ausnahmelisten der Virenscanner sind genauso lang wie die der Viren^^, das wird sich auch in Zukunft nicht ändern. Da brauche ich kein AutoIt auf dem Rechner, damit diesem so ist, leider!

    Zitat

    die Skript-Sprachen, zu denen AutoIt gehört, die algorithmisch nur eingeschränkte Möglichkeiten bieten

    Seit wann ist denn ein Algorithmus oder dessen Implementation abhängig von einer Programmiersprache? Es gibt Programmiersprachen, die sind für einige Algorithmen besser geeignet weil "Krücken" schon im Design dieser Sprache implementiert wurden, damit sie überhaupt benutzt wird!
    Mein letztes Statement zu deiner Aussage:

    Zitat

    Aber warum muss man nun jedes Problem in AutoIt lösen können wollen/müssen?

    Weil man so nicht C(++,#), Object Pascal, Fortran und Lisp auf seinem Rechner braucht und so mit der Zeit um diese Sprachen so zu lernen, daß man sie effektiv einsetzen kann, etwas besseres anfangen kann....zum Beispiel in Foren irgendwelchen (auch meist unwichtigen) Kram verzapfen :rofl:
    Hehe, eigentlich hast du völlig Recht. Gates hätte vor 30 Jahren schon mit dotnet (oder Java) anfangen sollen, dann müssten wir uns heute nicht mit 62459 Programmiersprachen auf 7625 Betriebssystemen rumschlagen.
    ciao
    Andy

    p.s.: am liebsten führe ich solche Diskussionen beim gleichzeitigen leeren einer geschmeidigen Flasche Spätlese in gemütlicher Runde, du bist herzlich eingeladen!

  • AspirinJunkie aka Namensvetter,
    vielen Dank für Deine DLL, allerdings sollte das "Ergebnis" die Position des Suchstrings im String ergeben, d.h. das erste (bzw alle) Vorkommen, also in deinem Beispiel mit den Vögeln die 5.
    Am Besten wäre eine Rückgabe aller Treffer in einem Array (jaja, gibt man den kleinen Finger, dann wollen diese Typen gleich den ganzen Arm und den anderen noch dazu :D:D:D ).
    ciao
    Andy

  • Hehe

    Wie ich schrieb hab ich ja nur erstmal das ganze 1:1 als DLL kompiliert - kein eigener Hirnschmalz ;)
    Hab mich mit meinen bescheidenen C-Kenntnissen doch mal rangesetzt und hab bis jetzt keine Lösung gefunden wie ich ein Array an AutoIt zurückgebe bzw.
    müsste ich erst mit einer ArrayList in C arbeiten weil die Anzahl der Treffer ja vorab nicht bekannt ist.
    Als Zwischenlösung hab ich dir erstmal eine kleine Übergangslösung per Callback-Funktion gemacht mit welchem du wenigstens erstmal die Positionen der Treffer in AutoIt angezeigt bekommst.
    Um daraus dann ein Array zu bekommen muss ich erstmal noch ne Nacht drüber schlafen oder jemand anderes der im Gegensatz zu mir wirklich Ahnung hat macht was draus (Source ist mit enthalten).

  • Thx jedenfalls vorab :thumbup:
    habe mal die 3 Kandidaten gegeneinander laufen lassen


    erst bei sehr großen stringlängen lohnt sich das, dein Boyer-Moore stürzt aber leider schon bei Patter mit einer Länge von über 20 Zeichen ab....seltsam