Ankündigung

Einklappen
Keine Ankündigung bisher.

Suche nach Performance

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Suche nach Performance

    Hallo,

    ich suche nach besserer Performance für mein Skript.
    In
    Code:
    $data
    wird ein String gespeichert. Die Information aus diesem String soll ausgewertet werden. Mögliche Werte sind von der Art:
    Code:
    $data = "output;0FFF"
    ,
    Code:
    $data = "output;0004"
    oder
    Code:
    $data = "input;ON"
    oder
    Code:
    $data = "input;OFF"
    Dabei nach "output" steht immer eine hexadezimale Zahl: "0FFF", "0004" oder eine andere.
    PHP-Code:
    <?
    $var = substr($data,0,6); // In $var steht 'output' oder 'input;'
    $hex = substr($data,-5); 

    //Auswerten und Setzen der Outputs
    // Z.B. $data = output;0008
    if ($var == 'output') {
            SetValueString($id_gerät, $hex);
            $bin = base_convert($hex, 16, 2); //Konvertiere hexadezimale Zahl nach binäre. 
    //Die führenden Nullen werden abgeschnitten (z.B. statt 001001 bekommt man 1001)
            //echo "binär ".$bin."\n";
            $str = (string)$bin; // Typumwandlung nach String
            $arr = array();
            
            if (strlen($str) < 12) { // Wenn die führenden Nullen abgeschnitten sind, dann hänge die 
    //am Anfang des Strings
                switch(strlen($str)) {
               case 1:
               $str = "00000000000".$str;
               break;
               case 2:
               $str = "0000000000".$str;
               break;
               case 3:
               $str = "000000000".$str;
               break;
               case 4:
               $str = "00000000".$str;
               break;
               case 5:
               $str = "0000000".$str;
               break;
               case 6:
               $str = "000000".$str;
               break;
               case 7:
               $str = "00000".$str;
               break;
               case 8:
               $str = "0000".$str;
               break;
               case 9:
               $str = "000".$str;
               break;
               case 10:
               $str = "00".$str;
               break;
               case 11:
               $str = "0".$str;
               break;
            }
        }
            
            for ($i = 0; $i < strlen($str); $i++) { // Mache aus String ein Array
                array_push($arr, substr($str, $i, 1));
            }
            $arr_rev = array_reverse($arr); // Setze Elemente im Array in umgekehrter Reihenfolge
            foreach($arr_rev as $key => $value) { // Kucke, an welchen Stellen die Einsen 
    //und an welchen Nullen stehen
                if ($value == 1) {
                
                switch ($key) {   // Key steht hier für port_out
                     case "0":
                    SetValueBoolean($id_0, true);
                    break;
                    case "1":
                    SetValueBoolean($id_1, true);
                    break;
                    case "2":
                    SetValueBoolean($id_2, true);
                    break;
                    case "3":
                    SetValueBoolean($id_3, true);
                    break;
                    case "4":
                    SetValueBoolean($id_4, true);
                    break;
                    case "5":
                    SetValueBoolean($id_5, true);
                    break;
                    case "6":
                    SetValueBoolean($id_6, true);
                    break;
                    case "7":
                    SetValueBoolean($id_7, true);
                    break;
                    case "8":
                    SetValueBoolean($id_8, true);
                    break;
                    case "9":
                    SetValueBoolean($id_9, true);
                    break;
                    case "10":
                    SetValueBoolean($id_10, true);
                    break;
                    case "11":
                    SetValueBoolean($id_11, true);
                    break;
                }
            }
            else {
             switch ($key) {   // Key ist port_out
                     case "0":
                    SetValueBoolean($id_0, false);
                    break;
                    case "1":
                    SetValueBoolean($id_1, false);
                    break;
                    case "2":
                    SetValueBoolean($id_2, false);
                    break;
                case "3":
                    SetValueBoolean($id_3, false);
                    break;
                    case "4":
                    SetValueBoolean($id_4, false);
                    break;
                case "5":
                    SetValueBoolean($id_5, false);
                    break;
                    case "6":
                    SetValueBoolean($id_6, false);
                    break;
                    case "7":
                    SetValueBoolean($id_7, false);
                    break;
                    case "8":
                    SetValueBoolean($id_8, false);
                    break;
                    case "9":
                    SetValueBoolean($id_9, false);
                    break;
                    case "10":
                    SetValueBoolean($id_10, false);
                    break;
                    case "11":
                    SetValueBoolean($id_11, false);
                    break;
                }
            }
        }
    }
    //Auswerten und Setzen der Inputs
    // Z.B. $data = input4;ON

    else {
      $port_in = substr($data, 5, 1); // Hier wird eine Nummer extrahiert, in diesem Fall $port_in = 4
       $status_in = substr($data, 7, strlen($data)-7); // Hier $status_in = ON
       echo $port_in."\n";
       echo $status_in."\n";
        SetValueString($id_gerät, $status_in);
        if (trim($status_in) == 'ON') {
            switch ($port_in) {
             case "0":
                SetValueBoolean($id_0 , true);
                break;
                case "1":
                SetValueBoolean($id_1 , true);
                break;
                case "2":
                SetValueBoolean($id_2 , true);
                break;
                case "3":
                SetValueBoolean($id_3 , true);
                break;
                case "4":
                SetValueBoolean($id_4, true);
                break;
                case "5":
                SetValueBoolean($id_5 , true);
                break;
                case "6":
                SetValueBoolean($id_6, true);
                break;
                case "7":
                SetValueBoolean($id_7, true);
                break;
                case "8":
                SetValueBoolean($id_8 , true);
                break;
                case "9":
                SetValueBoolean($id_9, true);
                break;
                case "10":
                SetValueBoolean($id_10, true);
                break;
                case "11":
                SetValueBoolean($id_11, true);
                break;
            }
        }
        else {
            switch ($port_in) {
                case "0":
                SetValueBoolean($id_0, false);
                break;
                case "1":
                SetValueBoolean($id_1, false);
                break;
                case "2":
                SetValueBoolean($id_2 , false);
                break;
                case "3":
                SetValueBoolean($id_3, false);
                break;
                case "4":
                SetValueBoolean($id_4 , false);
                break;
             case "5":
                SetValueBoolean($id_5, false);
                break;
                case "6":
                SetValueBoolean($id_6 , false);
                break;
                case "7":
                SetValueBoolean($id_7, false);
                break;
             case "8":
                SetValueBoolean($id_8, false);
                break;
             case "9":
                SetValueBoolean($id_9, false);
                break;
             case "10":
                SetValueBoolean($id_10, false);
                break;
                case "11":
                SetValueBoolean($id_11, false);
                break;
            }
        }
        
    }

    ?>
    Alles funktioniert, aber nicht ganz schnell, da es viele switch statements gibt. Ich würde mich sehr freuen, wenn jemand mir hinweist, wie ich das besser machen kann.
    Eventuell ist das mit bitweisen shift operatoren << und >> machbar. Aber wie?


  • #2
    Gruselig. Vieles wäre sicher mit trim und number_format kürzer. Aber viell. solltest DU lieber mal was Grundlegendes zum gewünschten Ergebnis sagen. Habe nämlich keine Lust, diesen Klumpen zu untersuchen.
    --

    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
    Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


    --

    Kommentar


    • #3
      Ich arbeite mit dem Gerät, das web i/o heißt. Es hat 12 output- und 12 input-ports. Das Gerät schickt regelmäßig eine Meldung, die in der Variable $data gespeichert wird.
      Die Meldung enthält die Information über die Änderungen der Belegung von input- und output-ports. Wenn gerade eine Änderung an einem output-port passiert, dann $data = "output;" gefolgt von einer hexadezimalen Zahl (z.B. "output;0007"). Hexadezimale Zahl zeigt, welche output-ports momentan belegt sind. Wenn man diese hex. Zahl nach eine binäre konvertiert, ist das leicht ersichtlich:
      Code:
      hexadezimal 0007
      entspricht
      binär   000000000111
      Auswerten soll man vom Ende der binären Zahl: die Einsen zeigen, welche ports belegt sind. Hier sind das ports 0, 1 und 2.

      Wenn gerade eine Änderung an einem input-port passiert, dann $data = "input#;ON" oder $data = "input#;OFF". Dabei ist # eine Zahl, Nummer von input-port. ON und OFF zeigen den Status vom input-port.

      Für jeden input- und output-port gibt es eine boolean Variable, insgesamt also 24 Stück. Nach erhalt der Meldung vom Gerät soll ich diese Meldung auswerten und die boolean Variablen entsprechend setzen. Wenn ein port belegt ist: true, wenn umgekehrt: false.

      Kommentar


      • #4
        Bin noch nicht sicher, ob ich das ganz raffe, was wo rausfällt.
        Aber vielleicht hilft Dir das schon mal:
        PHP-Code:
        <?php


        $pins 
        12;

        $hex '447';


        $dec intval ($hex 16);

        echo 
        '<pre>' decbin ($dec) , "\n\n"// nur für Kontrollzwecke

        $pinstatus = array ();
        for (
        $i $i $pins ; ++$i) {
          
        $pinstatus[$i] = (bool) ($dec);
          
        $dec $dec >> 1;
        }

        var_dump ($pinstatus);

        [edit]
        Weiss nicht genau, ob Du das so meintest:
        PHP-Code:
        <?php


        define 
        ('PORTS' 12);


        $data 'input10;ON';




        list (
        $type $value) = explode (';' $data);


        if (
        'input' == substr ($type 5)) {
          
        $pinstatus parseIn ($type $value);
        }
        elseif (
        'output' == $type) {
          
        $pinstatus parseOut ($type $value);
        }
        else {
          die (
        'error: mispelled input data');
        }




        function 
        parseIn ($type $value)
          {
          
        $port = (int) str_replace ('input' '' $type);
          
          
        $pinstatus array_fill (PORTS false);
          
        $pinstatus[$port] = 'ON' == $value;

          return (
        $pinstatus);
          }


        function 
        parseOut ($type $value)
          {
          
        $dec intval ($value 16);
          
          
        $pinstatus = array ();
          for (
        $i $i PORTS ; ++$i) {
            
        $pinstatus[$i] = (bool) ($dec);
            
        $dec $dec >> 1;
          }
          
          return (
        $pinstatus);
          }




        var_dump ($pinstatus);
        PS2:

        Noch ein bissel Eleganz:
        PHP-Code:
          for ($i $i PORTS ; ++$i) {
            
        $pinstatus[$i] = (bool) ($dec << $i);
          } 
        --

        „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
        Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


        --

        Kommentar


        • #5
          Vielen Dank,

          ich muss das ausprobieren. Das wird nächste Woche sein. Dann schreibe ich sofort eine Antwort.

          Eine Frage noch: kannst Du bitte zwei Ausdrücke erklären:
          PHP-Code:
          $pinstatus[$i] = (bool) ($dec);
              
          $dec $dec >> 1
          bzw.
          PHP-Code:
          $pinstatus[$i] = (bool) ($dec << $i); 
          und

          PHP-Code:
          $pinstatus array_fill (PORTS false);
            
          $pinstatus[$port] = 'ON' == $value
          Wäre sehr nett von Dir. Ich mag verstehen, was ich mache.

          Kommentar


          • #6
            >> ist eine Bit-Shift Operation nach rechts, d.h. alle Bits des Wertes werden nach rechts geschoben (links werden 0 nachgeschoben)

            & ist eine Bit-UND-Verknüpfung (boolsche Algebra)

            PHP-Code:
             $pinstatus[$port] = 'ON' == $value
            Hier wird der sog. 'ternäre' Operator ? : implizit verwendet.
            Im Grunde wird eine Abfrage gemacht ($value == 'ON'), deren Ergebnis in $pinstatus[$port] gespeichert wird.
            Anders ausgedrückt:
            PHP-Code:
            if ($value == 'ON'
              
            $pinstatus[$port] = true;
            else
              
            $pinstatus[$port] = false;

            // oder
            $pinstatus[$port] = ($value == 'ON') ? true false
            Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

            Kommentar


            • #7
              Ich muss true oder false an bestimmte IDs für INPUT und OUTPUT setzen.
              PHP-Code:
              switch ($key) {   // Key steht hier für port_out
                               
              case "0":
                              
              SetValueBoolean($id_0true);
                              break;
                              case 
              "1":
                              
              SetValueBoolean($id_1true);
                              break;... 
              Und das dauert lange.

              Kommentar


              • #8
                Ja und? nimmste halt $pinstatus[$port].

                Hier wird der sog. 'ternäre' Operator ? : implizit verwendet.
                Nicht wirklich. Dort wird nur das Ergebnis eines boolschen Vergleichs zugewiesen.
                --

                „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                --

                Kommentar


                • #9
                  Zitat von noch_anfaenger
                  aber nicht ganz schnell, da es viele switch statements gibt
                  Und das dauert lange.
                  Mich würde mal interessieren, woran du das festmachst. Wenn ich das langsamste Stück Code nennen sollte, hätte ich vermutlich auf eine der Funktionen getippt.

                  Kommentar


                  • #10
                    Vielleciht habe ich nicht richtig erklärt, was ich brauche. Ich brauche nicht das schöne Aussehen von meinem Code, sondern seine Schnelligkeit. Wenn ich jetzt den Beitrag von mermshaus lese, verstehe ich nur Bahnhof. Welche Funktionen sind gemeint?

                    Kommentar


                    • #11
                      Na ja, du sagtest, die Switch-Konstrukte seien zu langsam. Ich fragte mehr oder weniger interessehalber, woran du das festmachst. Ich hätte spontan getippt, array_reverse oder base_convert oder substr seien langsamer. Aber das wäre geraten gewesen.

                      Wahrscheinlich liegt die größte Geschwindigkeitsbremse ohnehin nicht im Code selbst, sondern im Initialisieren von PHP. Dazu wird dir sicher noch jemand eine kompetentere Antwort geben können.

                      Wie macht sich denn bemerkbar, dass das Script zu wenig performant ist? Vielleicht ist PHP die falsche Sprache.

                      Edit: ↓ Hm, guter Punkt, schätze ich.

                      Kommentar


                      • #12
                        Zitat von noch_anfaenger Beitrag anzeigen
                        Ich muss true oder false an bestimmte IDs für INPUT und OUTPUT setzen.
                        PHP-Code:
                        switch ($key) {   // Key steht hier für port_out
                                         
                        case "0":
                                        
                        SetValueBoolean($id_0true);
                                        break;
                                        case 
                        "1":
                                        
                        SetValueBoolean($id_1true);
                                        break;... 
                        Und das dauert lange.
                        Du hast deinen Flaschenhals bereits erkannt - es ist aber nicht das switch-statement, sondern SetValueBoolean. Vermutlich sendet die Funktion einen Wert an die angeschlossene Hardware.

                        Bei INP und OUTP muss ich immer an die Kommunikation mit der seriellen Schnittstelle unter MS-DOS denken. Die Übertragungsraten von dem Ding waren grauenhaft... tippe darauf, das sich das in diesem Fall ähnlich verhält.
                        Daher solltest du keine EINZELNEN Bits schicken, sondern immer ein komplettes Commandword zusammenbauen (12 bit bei dir) und das senden, also 12 Operationen zusammen - falls das überhaupt machbar ist.

                        Was sagt denn die Doku zu dem Gerät, wie schnell die Übertragungsrate ist (kann eventuell ja auch konfiguriert und erhöht werden?)
                        Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                        Kommentar


                        • #13
                          Zitat von lstegelitz Beitrag anzeigen
                          ...SetValueBoolean. Vermutlich sendet die Funktion einen Wert an die angeschlossene Hardware.
                          exakt!

                          Zitat von lstegelitz Beitrag anzeigen
                          Daher solltest du keine EINZELNEN Bits schicken, sondern immer ein komplettes Commandword zusammenbauen (12 bit bei dir) und das senden, also 12 Operationen zusammen - falls das überhaupt machbar ist.
                          Wie kann man das machen?

                          Zitat von lstegelitz Beitrag anzeigen
                          Was sagt denn die Doku zu dem Gerät, wie schnell die Übertragungsrate ist (kann eventuell ja auch konfiguriert und erhöht werden?)
                          Diese Frage kann ich jetzt nicht beantworten. Das ist aber ein sehr guter Hinweis!

                          PS. PHP ist eine Bedingung, die ich nicht ändern darf.

                          Frage an mermshaus: was ist "↓ Hm, guter Punkt, "?

                          Kommentar


                          • #14
                            Offtopic:

                            Zitat von noch_anfaenger Beitrag anzeigen
                            Frage an mermshaus: was ist "↓ Hm, guter Punkt, "?
                            Ein Kommentar zu lstegelitzens Beitrag eins drunter. Irgendwie verstehen wir uns nicht, habe ich das Gefühl. (Wie du die 12 Bits auf einmal schickst, dürfte übrigens auch am ehesten in der Doku des Geräts zu finden sein.)

                            Kommentar


                            • #15
                              Die Doku müsste dazu etwas sagen können.

                              Ich kenn das so, das die einzelnen Pins eine Bitposition im Commandword haben.

                              Um ein Bit an einer bestimmten Position zu setzen oder zu löschen verwendet man Bitoperationen:

                              PHP-Code:
                              // $cmdWord: bisheriges Commandword
                              // $pos: Bitposition (0...31)
                              // $clear: true/false (true: Bit soll gelöscht werden) 
                              // Rückgabe: neues Commandword
                              function setBit($cmdWord$pos$clear=false) {
                                
                              $bit << $pos;
                                if (
                              $clear$cmdWord $cmdWord & (~$bit); // bit löschen 
                                
                              else $cmdWord $cmdWord $bit// bit setzen

                                
                              return $cmdWord;

                              Damit kann man nun beliebige Bitpositionen manipulieren:
                              PHP-Code:
                              $cmdWord 0// Alle Bitpositionen sind 0

                              $cmdWord setBit($cmdWord0false); // Setze das 1. Bit 
                              $cmdWord setBit($cmdWord5false); // Setze das 6. Bit 
                              $cmdWord setBit($cmdWord8false); // Setze das 9. Bit 
                              // nun weist $cmdWord diese Bitfolge auf (Big Endian)
                              // 0000 0000 0000 0000 0000 0010 0100 0001

                              $cmdWord setBit($cmdWord12false); // Setze das 13. Bit 
                              $cmdWord setBit($cmdWord13false); // Setze das 14. Bit 
                              $cmdWord setBit($cmdWord5true); // Lösche das 6. Bit wieder
                              // 0000 0000 0000 0000 0110 0010 0000 0001 
                              (Code ungetestet)

                              Die Frage ist nun: Kennt die API deines I/O Gerätes eine Funktion, um ein komplettes WORD zu senden? Also eine Art Ersatz für SetValueBoolean()...
                              Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                              Kommentar

                              Lädt...
                              X