Ankündigung

Einklappen
Keine Ankündigung bisher.

AJAX Performance PHP Script Laufzeit + 1 Sekunde?

Einklappen

Neue Werbung 2019

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

  • AJAX Performance PHP Script Laufzeit + 1 Sekunde?

    Hallo Leute,

    ich bin recht frisch im AJAX, dennoch habe ich es geschafft ein Installer und einen Loader für mein Krempel zu entwickeln.
    Beim Installer ist es erwünscht das er sich erstmal 'ne Sekunde Luft schnappt bevor dieser loslegt/weitermacht da er mit ZIP Dateien beschäftigt ist und Eintragungen in die DB aufgrund des Zeitstempels mindestens eine Sekunde abstand halten sollen.

    Dennoch habe ich jetzt eine Operation die 4ms dauert und wo der Zeitstempel irrelevant ist und er nimmt sich weiterhin eine Sekunde Zeit bis er den nächsten Request abfeuert.

    Mathematisch sieht die Geschichte folgendermaßen aus: PHP=4ms + JS=1s also insgesamt mindestens 1004ms/Operation (oder ca. 200x langsamer als es könnte von der Performance her bei PHP)

    Getestet habe ich das im Firefox als auch im Google Chrome, meine Frage dazu da ich kein window.Timeout mehr verwende und kein usleep oder sleep mehr in meinen PHP-QCs habe, ist das Absicht/Normal?

    Ich konnte dazu nichts relevantes auf Google finden, notfalls kann ich das Problem auch anders lösen um die Performance in diesem PHP Script zu verbessern (Operationen stapeln bis die Sekunde fast voll ist und kurz vor Ablauf der Sekunde den Prozess bis zum nächsten Lauf unterbrechen).

    Jedenfalls wäre eine Antwort erstmal nicht schlecht, da es mir nicht ganz geheuer ist.

    OT: Bei Google bedeutet wohl AJAX eher Reinigungsmittel und @moma antworte nicht mehr auf meine Fragen wenn du dir den darauffolgenden Spruch nicht verkneifen kannst, nochmal als Antwort zu deiner Volksbankgeschichte da (die schenken einen nichts, nur zur Info) und geh deine 'Beiträge' woanders sammeln.

    Grüße theredox

  • #2
    Ich verstehe deinen Post noch nicht ganz... Und AJAX liefert bei mir durchaus gute Ergebnisse auf Google.

    Ich sehe erstmal folgende Probleme:
    - Du hast einen Installer (oder was auch immer), der darauf angewiesen ist, dass Requests nur alle Sekunden ankommen weil ansonsten irgendein Zeitstempel in einer DB blablabla... Das ist schon einmal schlecht, die Implementation darf nicht davon abhängen.

    - Irgendetwas mit usleep und window.timeout und kein Mensch weiss, was du eigentlich meinst. Zeige uns Code, das ist eine Sprache, die wir beide sprechen.

    - Du scheinst in Intervallen irgendetwas aufzurufen, dass chronologisch ablaufen muss. Das ist auch schon einmal eine schlechte Implementation.

    Kommentar


    • #3
      Wenn du bei deinem Installer auf einen synchronen Ablauf angewiesen bist und der Benutzer in der Zeit eh nicht agieren soll, dann kannst du den ajax-request auch synchron ausführen (blockt die UI). Alternativ beschäftige dich mit dem Konzept von Deferreds/Promises.

      Kommentar


      • #4
        Mh... werde mal aus der Datei mal Rückschlüsse ziehen, z.B. was die Latenz anbelangt, es läuft ja tatsächlich lokal auf einem Windows, aber die Sekunde ist auffällig, was mich weiterhin wundert ist wo dieses window.setTimeout herkommen soll und/oder wo die sleeps stecken sollen... ich habe keine drin, da bin ich mir einfach sicher hab mit np++ das alles gecheckt, es gibt nur 3 Funktionen die getrennt ein window.setTimeOut haben, die sind aber nicht aktiv ^^

        Ich melde mich dann mal dazu nochmal, wenn ich Neuigkeiten diesbezüglich habe.

        Könnte noch heute passieren. QC ist halt etwas kompliziert, das sind ca. 80KB Pro ausgabe und 5-7 Dateien^^.

        Grüße theredox
        Angehängte Dateien

        Kommentar


        • #5
          Was machst du da? Wenn du so viel hin- und herschicken musst, mach nen Socket auf.
          Was du dort als Latenz markiert hast, ist nicht die Latenz. So lange hats gebraucht, bis der Request verarbeitet wurde und die Antwort kam. Klick mal einen an und anschließend auf timing.

          Kommentar


          • #6
            So sieht der Spaß aus, die vollständigste Zeile die ich bekomme.
            Außerdem motzt Chrome an den Headers rum, aber darum hätte ich mich eher noch später gekümmert

            Blocking wäre jetzt für mich JS oder Waiting wäre jetzt für mich PHP (wenn es nicht durch den JS Interval geblockt wird). Vllt. ist da einfach eine Datei darin verwickelt die ich grade nicht finde, jedenfalls hab ich da auch in Erinnerung das ich das auch mit Absicht mal eingebaut habe.
            Das läuft ja alles Lokal, Windows 7 und XAMPP Apache...

            Muss ich mir nochmal genau anschauen... :/

            Kommentar


            • #7
              Nö. Blocking ist die Zeit, die der Browser darauf wartet, bis er ne Verbindung aufmachen kann. IE9 bspw. kann nur zwei TCP-Verbindungen per XHR gleichzeitig aufmachen, Chrome sechs. https://developer.chrome.com/devtool...network-timing

              Waiting ist nicht nur PHP, sondern die Zeit, die es dauert, bis der Server ne Antwort schickt, also auch DNS Roundtrip, Webserver, ...

              Ich glaube, du hast da konzeptionell nen Wurm drin. Also nochmal: Was machst du da bzw. wieso brauchst du so viele Verbindungen?

              Kommentar


              • #8
                Also generell erstelle ich damit gerade ein Suchindex:
                Ein kleiner Auszug.

                - onClick ajax(PHP Datei, a, b) -- (a/b)
                es wird gezählt und a=1 und b=mysql_num_rows von Tabelle 3 gesetzt //beispiel (1/2000)

                if ajax(a < b){
                -öffne csv datei
                -nimm die erste CSV Zeile pack den rest in den buffer
                -ziehe name, titel beschreibung Hauptsprache - (mySQL Tabelle 1)
                -ziehe name, titel beschreibung Nebensprache - (mySQL Tabelle 2)
                -suche nach relevanten wörtern innerhalb der strings
                -priorisierung und entfernung von doppelten vorkommen innerhalb eines strings, und möglicherweise noch weitere operationen zur optimierung
                -eintrag in MySQL Tabelle 3 - Index für die 'Hauptsprache' || Tabelle 4 - Index für die 'Nebensprachen'
                -Schreibe buffer als neue CSV Datei
                -response für ajax (phpdatei=soundso.php, a=2, b=2000)
                ajax(php datei, a, b);
                }

                Ich schätze mal der Vorgang dauert insgesamt 40ms / Vorgang wenn alles fertig ist, was ich ja auch machen kann ist die Anfrage mit der Schleife so lange zu verzögern, bis die Sekunde voll ist so dass in der Schleife nicht nur eine Operation gelaufen ist sondern ca. 25 Operationen pro Lauf (bzw. soviele bis eine Sekunde voll ist.
                Sowohl das JS als auch das PHP Skript sind darauf ausgelegt sequentiell alle Vorgänge abzuarbeiten.
                Dem Javascript ist es egal ob nur ein Vorgang oder 25 Vorgänge durchgeführt werden, sofern es mitgeteilt wird.

                Heisst ich locker den Umgang mit a innerhalb der PHP Datei und kriege so mehr Performance.

                Wenn es da ein Limit gibt, dann richte ich mich nach den Defaults die mir die Browser vorgeben, dann muss ich in ein solchen Vorgang halt mehr Zeit füllen und mehr erledigen.

                >| Also jetzt wäre es ja: blocking - mache eine Sache für 4ms (a=a+1) -> gebe zurück
                >| Danach wäre es dann: (blocking?) - mache soviel du kannst für (fast oder knapp mehr als) eine Sekunde(a=a+x) -> gebe zurück

                Das wäre ja schonmal eine Performancesteigerung, die Frage die ich mir stelle ist was mit dem (blocking?) dann passiert...
                Das umbauen von PHP ist an sich ist kein Problem innerhalb dieser Struktur, dafür hab ich die ja mal gebaut.

                Parallel kann ich das alles nicht abarbeiten, da ich die CSV Dateien nicht nach belieben aussernanderpflücken kann.

                Du hast ja gefragt was ich vorhabe, entsprechend fällt der Text etwas länger aus, ich hoffe es ist verständlich was ich meine.

                Grüße: theredox

                Kommentar


                • #9
                  Wenn die Analyse noch nicht fertig ist, würde ich dir ElasticSearch ans Herz legen wollen. Damit hättest du ein performantes Analysewerkzeug, das du einfach abfragen kannst (mit einem http request, bspw jsonp oder cors).

                  Wenn du deinen Ansatz weiter verfolgen willst, würde ich von PHP so viele Ergebnisse auf einmal zurückgeben wie du auf einmal darstellst (bspw. 10 o.a. alle 25). 25 Requests sind in dem Kontext zu viel. Alternativ kannste auf Websockets umschwenken, dann verschickst du die Datensätze auch einzeln und der HTTP Overhead reduziert sich auf ein Minimum.

                  Für den XHR Ansatz:
                  PHP-Code:
                  function search(query) {
                    
                  this.data = {
                      
                  query query,
                      
                  limit 10,
                      
                  start 1
                    
                  }
                  }

                  search.prototype = {
                    
                  request : function (data) {
                      return $.
                  ajax({
                        
                  url '/search',
                        
                  data this.data,
                        
                  context this
                        
                  //..
                      
                  })
                    },
                    
                  run : function() {
                      
                      
                  this.request()
                        .
                  done(function(response) {
                          if(
                  response.data.pending) {
                            
                  data.start += data.limit;
                            
                  this.request(data);
                            return;
                          }
                          
                  console.log('fi.')
                        })
                    }


                  Kommentar


                  • #10
                    Der Screenshot aus Posting #6 zeigt das die Latenz Serverseitig ist. Da die Calls sequentiell ausgeführt werden wird dir da auch kein Limit seitens des Browsers im Weg stehen. Die ganze Geschichte klingt aber sehr abenteuerlich. Der Overhead für einen Request ist wahrscheinlich um Faktor 100 größer als eine einzelne Zeile zu indizieren. Mir ist so oder so ein Rätsel warum du das im Sekundentakt machen willst? Willst du damit den Fortschritt darstellen? Dafür gibt es auch bessere Möglichkeiten.

                    Kommentar


                    • #11
                      Sicher? Ich denke, der TE hat so viele Requests gleichzeitig aufgemacht, dass der Browser die Requests teilweise geblockt hat.

                      Kommentar


                      • #12
                        Zitat von rudygotya Beitrag anzeigen
                        Sicher? Ich denke, der TE hat so viele Requests gleichzeitig aufgemacht, dass der Browser die Requests teilweise geblockt hat.
                        Ja. Du hast es doch auch selbst geschrieben. Blocking = Browser Limit, Sending = Request senden, waiting = warten auf das erste Byte der Response, receiving = erstes bis letztes Byte. Siehst du auch (schlecht) in Posting 4. Die Request bilden eine schräge Linie, würden sie gleichzeitig laufen würde eine Treppe entstehen.

                        Code:
                        Schräge:
                        #
                         #
                          #
                           #
                        
                        Treppe:
                        #
                        #
                        #
                        ##
                        ##
                        ##
                        ##
                        ####
                        ####
                        ####
                        ...

                        Kommentar


                        • #13
                          Ja ich hab das Sequentielle vorerst erstmal umgestellt die aktuelle Performance liegt bei ca. 6 operationen die sekunde, die Schleife läuft so lang bis die Sekunde voll ist mit microtime(), Serverseitig von PHP kontrolliert.

                          Ich schätze mal das die Performance unter anderem auch grottig ist, da dieser eine mysql_update Sequenz ohne eindeutigen Identifikator (ja auch Renundanzgefährdet) stattfindet, die Latenz einer solchen operation liegt zwischen 40-166ms innerhalb des php Abschnitts (ab und zu rechnet der unfug die 40 ms halte ich für unrealistisch).

                          erc Der Google Chrome motzt bei mir den XHR Header nicht an, jedoch ist der mit dem unsafe Header 'Content-length' und 'Connection' mit der Meldung 'Refused to set unsafe header' dabei.

                          Eine Treppe ist an sich schon beabsichtigt, ich bin schon froh wenn mir unendliche Tipparbeit erspart bleibt und ich immer gut feststellen kann wo noch ein Fehler ist, ausserdem kann ich die sequentielle Struktur auch nicht verwerfen da Sie mir die Kontrolle auch immens vereinfacht.

                          Mein Problem ist zur Zeit eher der Abstand und die Performanceauslastung um deinem Treppenmodell zu folgen erweiter ich das mal ein bisschen.

                          Code:
                          Beispiel Eins: (Zustand zu Beginn des Threads)
                          #<- ich tu nix ->#<- ich tu nix -># ...
                          >Ich tu nix ist eine Sekunde
                          >Auslastung: 2op von 12 in 2 Sekunden(Performance pro Lauf: 16.6%)
                          
                          Vermuteter ist Zustand:
                          #<- ich tu nix ->#<- ich mache was -># ...
                          > Abstände auch bei ca. 1 Sekunde
                          > Auslastung: 6op von 12 nahe 2 Sekunden (Performance pro Lauf: 45-55%)
                          
                          Beispiel Zwei: (Idealzustand)
                          #<- ich mache was ->#<- ich mache was -># ...
                          > Abstände optional 500ms-1s für den Refresh
                          > Auslastung: 12 op von 12 in 2 Sekunden (Performance pro Lauf: nahe 100%)
                          Die Latenz innerhalb des Servers schwankt auch, da ich das alles Lokal mit stinknormalen XAMMP fahre mit Windows 7, sind halt auch nicht die besten Voraussetzungen für einen Server, dennoch bringt es auch andere Vorteile mit da ich lokal mit bis zu 50MB/s r/w arbeiten kann.

                          Grüße theredox

                          Kommentar


                          • #14
                            Ich habe gelesen, das es auch daran liegen könnte das diese blocking Zeit durch PHP erzeugt wird aufgrund der Nutzung von Sessions.

                            http://codingexplained.com/coding/ph...locking-in-php

                            Heißt, das der exklusiv Lock an der Session hängt, darauf muss man auch erstmal kommen oO.

                            Dies ermöglicht ja unter anderem auch den Betrieb von paralelen Aufrufen, was ich zwar nicht möchte, mir reicht es ja wenn es sequentiell bleibt, hauptsache die blocking time ist weg.

                            Irgendeine Zusatzinfo zum Thema Sessions, ich muss sagen damit habe ich fast gar nicht gearbeitet... Kann das sein, was ist da wichtig?

                            PHP-Code:
                            session_start(); $_SESSION['some'] = 'value'session_write_close(); // From here on out, concurrent requests are no longer blocked 
                            Also ich versteh grad nur Bahnhof oO

                            Edit: ich mache fast gar nichts mit session ?!?!

                            Kommentar


                            • #15
                              Wenn zwei Anfragen zeitgleich auf die gleiche Session zugreifen wollen, blockieren sie sich gegenseitig. Die Session darf immer nur von einem Thread zur gleichen Zeit gelesen/geschrieben werden. session_write_close() macht genau das: es schreibt die herumlungernden Daten ins Sessionfile und schliesst dieses - anschliessend darf ein anderer Thread sie öffnen und bearbeiten (aber: im aktuellen Thread ist dann *kein* Sessionzugriff mehr möglich, bis man erneut session_start() aufruft, was aber wiederum zu einer Blockierung führen kann, wenn der andere Thread die Session noch geöffnet hat)

                              Edit: ich mache fast gar nichts mit session ?!?!
                              Was heisst "fast gar nichts"? Es reicht ein session_start() um das Sessionfile zu öffnen und damit zu blockieren...

                              Kommentar

                              Lädt...
                              X