Geschwindigkeit

  • Hallo Zusammen,

    es geht bei meiner Frage um die bessere Performance!

    Ich will diesen String auslesen: "Plot1[TAB]C:\Testordner\Testdatei.test"
    Ich habe hier zur besseren Verdeutlichung die Tabs in eckige Klammern geschrieben.

    Zur Aufgabe:
    Ich habe eine Datei, die um die 10.000 solcher Einträge enthält. Dabei kann sich der jeweilige Pfad ändern und das "Pot1" kann "Plot2", "default", oder "graphics" annehmen. Weitere Einträge könnten folgen.

    Nun ist die Frage, wie ich weiter machen soll. Ist ein regulärer Ausdruck schneller, als die String-Funktionen?
    Ich müsste nämlich zu jeder Zeile den Pfad auslesen und den dazugehörigen Status auslesen.
    Meine Überlegung wäre, das [Tab] zu finden und dann alles andere mit StringTrimRight und StringTrimLeft auslesen.
    Aber wie schnell wird dieses? Ich bräuchte dazu ja minimal 3 String-Funktionen.

    Danke schon einmal für die hilfreichen Infos,
    Anna :party:

    Die Anna :*

    "Wo kämen wir hin, wenn jeder sagte wo kämen wir hin, und niemand ginge, um zu sehen, wohin wir kämen, wenn wir gingen..." :wacko:

    Einmal editiert, zuletzt von AnnaM (3. Dezember 2012 um 18:37)

  • String-Funktionen nutzen regüläre Ausdrücke. In deinem Fall wird es im vergleich zu manuellen Regexp kaum einen Unterschied machen.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Ist die Geschwindigkeit hier wirklich so essenziell? Auf meinem PC brauche ich für eine Testdatei mit 10.000 Einträgen gerade mal 16 Millisekunden.

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

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

    $sRead = FileRead(@ScriptDir & "\Test.txt")

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

    $t = TimerInit()
    $aRes = StringRegExp($sRead, "(?m)^(Plot1|Plot2|default|graphics)\t(\H+)$", 3)
    $t = TimerDiff($t)

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

    _ArrayDisplay($aRes, "Time: " & Round($t))

    [/autoit]

    @chess Erstens brauchst du dann mehr als ein StringSplit, weil du ansonsten immer beide Teile in einem Array Element hast. Zweitens braucht dieses Testscript bei mir 44 Millisekunden, das ist also weder definitiv, noch schneller als Regex.
    Ich würde sagen es macht einfach keinen Unterschied wie chip schon sagte (besonders nicht wenn man das zweite Script noch optimiert). Also soll die Anna entscheiden was für ihre Zwecke besser ist. ;)

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

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

    $sRead = FileRead(@ScriptDir & "\Test.txt")

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

    $t = TimerInit()
    $aRes = StringSplit($sRead, @CRLF, 1)
    ;~ _ArrayDisplay($aRes)
    Dim $aNew[$aRes[0] + 1][2] = [[$aRes[0]]]
    For $i = 1 To $aRes[0] - 1
    $aTmp = StringSplit($aRes[$i], @TAB, 2)
    $aNew[$i][0] = $aTmp[0]
    $aNew[$i][1] = $aTmp[1]
    Next
    $t = TimerDiff($t)

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

    _ArrayDisplay($aNew, "Time: " & Round($t))

    [/autoit]
  • String-Funktionen nutzen regüläre Ausdrücke.


    Verwechselst du _StrinBetween, was definitiv genauso wie _StringProper RegEx benutzt, mit StringSplit? Oder hast du den Source des AutoItinterpreters?

    name22:

    Dabei kann sich der jeweilige Pfad ändern und das "Pot1" kann "Plot2", "default", oder "graphics" annehmen. Weitere Einträge könnten folgen.

    Damit würde meine Enrscheidung bei so kleinen Unterschieden zugunsten _StringBetween fallen, denn das Anpassen des Source dauert länger als die gesparte Zeit durch RegEx.

    mfg autoBert

    Einmal editiert, zuletzt von autoBert (2. Dezember 2012 um 17:52)

  • Definitiv verwendet StringSplit() keine Regulären Ausdrücke. Das gilt nicht für String UDF Funktionen, das ist richtig.

    2 Mal editiert, zuletzt von minx (2. Dezember 2012 um 19:18)


  • Verwechselst du _StrinBetween, was definitiv genauso wie _StringProper RegEx benutzt, mit StringSplit? Oder hast du den Source des AutoItinterpreters?


    mfg autoBert

    Logische Schlussfolgerung.


    Definitiv verwendet StringSplit() keine Regulären Ausdrücke.

    Was dann ;)?

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Zitat von name22


    @chess Erstens brauchst du dann mehr als ein StringSplit, weil du ansonsten immer beide Teile in einem Array Element hast. Zweitens braucht dieses Testscript bei mir 44 Millisekunden, das ist also weder definitiv, noch schneller als Regex.


    Wo brauche ich denn bitte hier mehrere StringSplit's?

    [autoit]


    #include <Array.au3>

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

    $sString = "Plot1" & @TAB & "C:\Testordner\Testdatei.test"
    $aResult = StringSplit($sString,@TAB)
    _ArrayDisplay($aResult)

    [/autoit]

    lg chess

  • Logische Schlussfolgerung.

    Statt einfach mal eine nüchterne Erklärung zu bieten, wieder mal so richtig typisch chip. Komm doch mal von deinem Ross runter und erleuchte uns.

    2 Mal editiert, zuletzt von minx (2. Dezember 2012 um 19:18)

  • Zitat von chesstiger

    Wo brauche ich denn bitte hier mehrere StringSplit's?


    Sobald du mehr als eine Zeile hast :P.

    [autoit]

    #include <Array.au3>

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

    $sString = "Plot1" & @TAB & "C:\Testordner\Testdatei.test" & @CRLF & "Plot2" & @TAB & "C:\Testordner\Testdatei.test"
    $aResult = StringSplit($sString,@TAB)
    _ArrayDisplay($aResult)

    [/autoit]
  • Definitiv verwendet StringSplit() keine Regulären Ausdrücke. Das gilt nicht für String UDF Funktionen, das ist richtig.

    Statt einfach mal eine nüchterne Erklärung zu bieten, wieder mal so richtig typisch chip. Komm doch mal von deinem Ross runter und erleuchte uns.

    Leg ich dir halt mal den Arm aus der Sonne: http://msdn.microsoft.com/de-de/library/…=vs.110%29.aspx


    Und nun bist du dran minx, beweise mal das nicht Regexp benutzt.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

    Einmal editiert, zuletzt von chip (2. Dezember 2012 um 18:18)

  • Zitat

    Ja, ich bin davon ausgegangen, dass die Datei bereits als Array vorliegt


    Das hört sich zwar im ersten Beitrag nicht so an, aber in so einem Fall wäre StringSplit natürlich schneller. StringRegExp lohnt sich oft erst bei komplexen Aufgaben wo mehr als 2 String* Funktionen nötig sind.

  • Leg ich dir halt mal den Arm aus der Sonne: http://msdn.microsoft.com/de-de/library/…=vs.110%29.aspx


    Und nun bist du dran minx, beweise mal das nicht Regexp benutzt.

    OK,jetzt weis ich warum du folgerst dass AutoIt es so macht. Ich habe aber kein .NET Framework 4.5 installiert und bisher auch nirgends gelesen dass AutoIt überhaupt irgendein .NET Framework benötigt. Trotzdem funktioniert StringSplit bei mir also kann (muss aber nicht)deine Folgerung auch ein Trugschluss sein. Da AutoIt lt. Hilfe auch mit Win 95 läuft drängt sich bei mir der Verdacht auf, dass dies so ist.

    mfg autoBert

  • Ich denke mal das hier sollte die Diskussion klären:

    Spoiler anzeigen


    Ich persönlich sehe das kein RegEx.
    Ist zwar von der 3.1.0 aber ich denke, da hat sich nichts geändert:
    http://www.autoitscript.com/autoit3/files/…-v3.1.0-src.exe

  • Na ^^
    Vielleicht hat sich was geändert, aber ich glaube das nicht.

    Es hätte ja auch nach dem Prinzip funktionieren können, aber das wäre, wie gesagt, sinnlos dann die Funktion gleichwertig anzubieten. Aber schön mal zu sehen wie so etwas funktioniert (und NET Framework habe ich auch nicht ^^)

  • Na ^^
    Vielleicht hat sich was geändert, aber ich glaube das nicht.

    Es hätte ja auch nach dem Prinzip funktionieren können, aber das wäre, wie gesagt, sinnlos dann die Funktion gleichwertig anzubieten.


    Sinnlos ist angesichts der Zeitunterschiede die Diskussion darüber was besser ist, denn


    Damit würde meine Enrscheidung bei so kleinen Unterschieden zugunsten _StringBetween fallen, denn das Anpassen des Source dauert länger als die gesparte Zeit durch RegEx.

    mfg autoBert

  • autoBert Ehrlich gesagt finde ich nicht, dass da eines flexibler ist als das andere..
    So könnte man das ganze noch vereinfachen. Man kann so viele Statusstrings hinzufügen wie man will und muss sie nur durch ein "|" Symbol trennen. ;)

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

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

    $sStatus = "Plot1|Plot2|default|graphics"
    $sRead = FileRead(@ScriptDir & "\Test.txt")

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

    $t = TimerInit()
    $aRes = StringRegExp($sRead, "(?m)^(" & $sStatus & ")\t(\H+)$", 3)
    $t = TimerDiff($t)

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

    _ArrayDisplay($aRes, "Time: " & Round($t))

    [/autoit]
  • autoBert Ehrlich gesagt finde ich nicht, dass da eines flexibler ist als das andere..


    Bei der StringSplit-Methode brauchtr man sich um nichts kümmern, wenn ein neuer Begriff auftaucht wird diese Zeile trotzdem autmatisch getrennt.
    Bei der RegEx-Methode muss man das Skript anpassen und dies dauert länger als einige Millisekunden, vor allem muss man daran denken ansonsten werden Zeilen unterschlagen.

    mfg autoBert

  • OK,jetzt weis ich warum du folgerst dass AutoIt es so macht. Ich habe aber kein .NET Framework 4.5 installiert und bisher auch nirgends gelesen dass AutoIt überhaupt irgendein .NET Framework benötigt. Trotzdem funktioniert StringSplit bei mir also kann (muss aber nicht)deine Folgerung auch ein Trugschluss sein. Da AutoIt lt. Hilfe auch mit Win 95 läuft drängt sich bei mir der Verdacht auf, dass dies so ist.

    mfg autoBert

    Diese Funktion ist keine explizieter Bestandteil von .NET Framework 4.5. Du kannst das sogar über native C++ mit split_regex bis native C mit strtok runterbrechen.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.