Ankündigung

Einklappen
Keine Ankündigung bisher.

Base64 encode / decode 50MB String

Einklappen

Neue Werbung 2019

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

  • Base64 encode / decode 50MB String

    Hallo Leute,

    Ich habe jetzt schon viel gegoogelt aber nix passendes gefunden.

    Folgendes Problem:
    Ich bekomme über einen Soap Client eine Xml String in der unter anderem eine Datei im Base64 format liegt.
    Nachdem ich die Datei mit Simplexml eingelesen habe, konvertiere ich den string mit base64_decode.

    Und hier liegt das Problem..
    Für das decode werden 300-500mb ram benötigt.
    Werden jetzt mehrere Datein parallel geschickt , übersteigert das schnell den Ram.

    Ich habe gelesen das man die Datei "String" in Chunks konvertiert werden sollte. Konnte aber nix finden was mir weiterhilft..

    Habt ihr ne Lösung für mich, wie ich Datein ohne viel ram decode und encode bekomme?

    Vielen Dank

    Gesendet von meinem SM-G901F mit Tapatalk


  • #2
    Willkommen im Forum. Kurze Rückfrage: Wie misst du denn den RAM, den das Dekodieren benötigt?

    Kommentar


    • #3
      Schau dir mal das hier an:
      - https://github.com/prewk/xml-string-streamer
      - http://php.net/manual/de/filters.convert.php

      Grundsätzlich wäre aber eine Antwort auf mermshaus Frage interessant bei einer möglichen Umsetzung.
      [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

      Kommentar


      • #4
        Hallo,

        Gemessen habe ich mit php mittel memory_get_peak_usage und den boardmitteln von linux um den ram verbrauch zu sehen!

        Gesendet von meinem SM-G901F mit Tapatalk


        @tr0y
        Ich habe kein Problem beim parsen der Xml ("vermutlich"), weil ich könnte auch direkt aus einer Datei lesen get contents und dan konvertieren, da hätte ich die gleichen Probleme

        Kommentar


        • #5
          Ich habe mir mal kurz die C-seitige Implementierung von php_base64_decode_ex angeschaut; da sollte eigentlich nicht mehr als 50 MB zusätzliche RAM verbraucht werden für einen 50 MB String.

          Bist du dir sicher, dass es direkt am base64_decode liegt? (Und nicht bspw. daran, dass die Strings noch in der RAM bleiben nach den einzelnen Decodes?)

          Ansonsten, base64 ist generell in Chunks von 4 Bytes unterteilt; d.h. man kann den String in ein Vielfaches von 4 Bytes unterteilen und dann diese Unterteilungen einzeln dekodieren.

          Kommentar


          • #6
            Auch ein kurzer Test ergibt den erwartbaren Speicherverbrauch:

            PHP-Code:
            <?php

            var_dump
            (memory_get_peak_usage());  // int(235296)       ~0 MB (Grundverbrauch)

            $s str_repeat('x'50 1000 1000);
            $encoded base64_encode($s);

            var_dump(memory_get_peak_usage());  // int(116899960)  ~120 MB ($s, $encoded)

            $decoded base64_decode($encoded);

            var_dump(memory_get_peak_usage());  // int(183566784)  ~180 MB ($s, $encoded, $decoded)
            (Das kann man noch etwas drücken, indem man nicht mehr benötigte Inhalte (wie hier $s) „freigibt“ ($s = null;). Ist aber für das Beispiel hier nicht relevant.)

            Daher jedenfalls die Nachfrage. Ich hätte gedacht, dass da das SimpleXML-Zeug mitgemessen wurde. Das scheint aber ja (Beitrag #4) nicht der Fall zu sein.

            Aber wie auch immer: Unter ~100-150 MB ist es mit base64_decode wohl so oder so nicht hinzubekommen. Für speichereffiziente Lösungen muss was her, das mit Streams arbeitet. Siehe tr0ys Antwort.

            Kommentar


            • #7
              Soll ich mich wirklich so vertun? Und das Problem an anderen $Strings liegen... ich werde am Mittwoch selber es nochmal testen und Berichten..


              Gesendet von meinem SM-G901F mit Tapatalk

              Kommentar


              • #8
                Hallo,

                also da es im Base64 Format kommt ist es schwierig die Datei in kleinen Stücken anzupacken um sie direkt verarbeiten zu können. Ich würde hier ein zwischenspeichern der enkodierten Datei auf der Festplatte empfehlen. Danach kann man ja die Datei mit einem XML StreamReader stückchenweise einlesen und verarbeiten. Beim einlesen würde ich Dir das Monitor Prinzip empfehlen. Das heißt maximal eine Datei gleichzeitig. Oder Alternativ geht auch ein Ring Buffer. Das heißt es dürfen z. B. maximal 3 Streams gleichzeitig offen sein.


                MFG derwunner

                Kommentar


                • #9
                  Zitat von derwunner Beitrag anzeigen
                  Hallo,

                  also da es im Base64 Format kommt ist es schwierig die Datei in kleinen Stücken anzupacken um sie direkt verarbeiten zu können. Ich würde hier ein zwischenspeichern der enkodierten Datei auf der Festplatte empfehlen. Danach kann man ja die Datei mit einem XML StreamReader stückchenweise einlesen und verarbeiten. Beim einlesen würde ich Dir das Monitor Prinzip empfehlen. Das heißt maximal eine Datei gleichzeitig. Oder Alternativ geht auch ein Ring Buffer. Das heißt es dürfen z. B. maximal 3 Streams gleichzeitig offen sein.


                  MFG derwunner

                  Öh nö, weit weg von schwierig. Siehe #3
                  [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

                  Kommentar

                  Lädt...
                  X