Warum ist C++ hier langsamer?



  • Grund für das "Auf und Zumachen" ist eben, weil ich das Programm ursprünglich über PHP ausgeführt habe (und hier wird das Programm 100 mal hintereinander ausgeführt).

    Das bzgl. std::string ist mein Fehler - wusste ich nicht besser.



  • Ich kenn mich mit PHP nicht aus. Aber es scheint so, als legst du in PHP nur 1x einen Stream an, in C++ legst du aber 101x einen Stream an. Wenn ich das Ganze mal verbessere braucht dein Quellcode mit argc=2 3ms bei mir.



  • file_put_contents macht das File auch jedes mal auf, schreibt dann, und machts dann wieder zu.
    http://php.net/manual/en/function.file-put-contents.php

    Aber ersetz einfach mal std::ios_base::app durch std::ios_base::ate.
    Das sollte mMn. einiges bringen.



  • Das sieht auch sehr lustig aus:

    log_message += (std::string) + argv[i] + (i != (argc - 1) ? " " : "");
    

    Sieht aus, als sei

    log_message += std::string() + argv[i] + (i != (argc - 1) ? " " : "");
    

    gemeint, aber in Wirklichkeit ist der erste Term ein unäres Plus, angewandt auf argv[i] , was dann nach std::string gecastet wird. Dabei ist das gar nicht so schlecht, nur sollte man es dann auch so schreiben (ohne das + natürlich):

    log_message += std::string(argv[i]) + (i != (argc - 1) ? " " : "");
    


  • Wie gesagt, ich programmiere C++ nur hin und wieder 😉

    Zu dem Tipp bzgl. std::ios_base::ate - sehr interessant, direkt auf 0.02 bis 0.04 Sekunden runter. Danke.

    Mein eigentliches Ziel aber habe ich nicht erreicht. Es liegt nicht an der Geschwindigkeit des C++-Programms, sondern an "exec" selbst. Ich wollte versuchen, den Logger über ein nativ geschriebenes Programm auszuführen um so mehr Geschwindigkeit rauszuholen - das exec so langsam ist, wusste ich nicht.

    Scheinbar ist die von beispielsweise Facebook genutzte Lösung, Scribe, dann wohl die einzig schnellere um das Logging schneller hinzukriegen.



  • Der Doppelpost sei entschuldigt, aber mir fiel gerade auf: keine Ahnung wo das Plus herkommt, in meinem Programm siehts eigentlich so aus:

    log_message += (std::string)argv[i] + (i != (argc - 1) ? " " : "");
    

    Vermutlich das Überbleibsel von irgendwelchen Tests die ich gestern noch angestellt hatte.


  • Mod

    Compilierte Sprachen machen Dateioperationen, Internetverbindungen, usw. nicht magisch schneller. Compilierte Sprachen können schnell rechnen. Man schreibt kein C++-Programm, damit dies schneller in Dateien schreibt. Das Schreiben in die Datei ist es, was die Geschwindigkeit bestimmt, egal welche Sprache. Du bekommst eben höchstens noch Overhead durch die zusätzliche Programmdatei, die hier komplett starten und beenden muss. Ich kenne php nicht, aber wenn ich das Handbuch richtig verstehe startet exec sogar eine ganze Subshell, was dann wirklich mörderisch für die Geschwindigkeit wäre. Was du ja auch misst.



  • Lokart schrieb:

    Scheinbar ist die von beispielsweise Facebook genutzte Lösung, Scribe, dann wohl die einzig schnellere um das Logging schneller hinzukriegen.

    Nein, GANZ sicher nicht die einzige.
    Du kannst in C++ Extensions für PHP entwickeln. Also quasi Funktionen in C++ implementieren die du aus PHP dann direkt aufrufen kannst -- genau so als wenn es "echte" PHP Funktionen wären.

    Diese können dann beliebig schlaues Caching/Coalescing machen, und dadurch die Logging-Geschwindigkeit quasi beliebig steigern.

    Du kannst aber auch, was viel einfacher wäre, deinen eigenen Logging-Funktionen in PHP so schreiben, dass sie einfach nicht das File dauernd auf- und wieder zumachen. Damit wirst du langsamer sein als mit einer "schlauen" C++ Extension, aber immer noch viel schneller als jetzt.

    Oder du verwendest einen Logging-Daemon, der über Sockets oder Pipes Verbindungen annimmt, und alles was auf diesen Verbindungen ankommt in das Logfile schreibt. Der Logging-Daemon wäre dann wieder in etwas anderem als PHP implementiert, damit er asynchrone IO Funktionen, Threads und was nicht noch alles verwenden kann um das Schreiben von vielen kleinen Datenstückchen in ein gemeinsames Logfile zu beschleunigen.



  • "Einzige" war wohl das falsche Wort, stimmt.

    Du kannst in C++ Extensions für PHP entwickeln. Also quasi Funktionen in C++ implementieren die du aus PHP dann direkt aufrufen kannst -- genau so als wenn es "echte" PHP Funktionen wären.

    Diese können dann beliebig schlaues Caching/Coalescing machen, und dadurch die Logging-Geschwindigkeit quasi beliebig steigern.

    "Beliebig"? Ich weiß nicht, wie die entsprechenden Funktionen in PHP momentan in implementiert sind - vlt. sind diese ja schon relativ gut optimiert? Keine Ahnung.

    Du kannst aber auch, was viel einfacher wäre, deinen eigenen Logging-Funktionen in PHP so schreiben, dass sie einfach nicht das File dauernd auf- und wieder zumachen. Damit wirst du langsamer sein als mit einer "schlauen" C++ Extension, aber immer noch viel schneller als jetzt.

    Was i.d.R. nicht unter realen Bedingungen funktioniert. Normalerweise loggt man auf einer Seite ja nicht 100 Sachen auf einmal, sondern nur ein paar Dinge. Ändert man den Request, muss der Interpreter erneut ran und die Datei wieder aufmachen. Wie man den Stream über mehrere Requests offen lassen könnte, wäre mir nicht bekannt (vor allem, da der Interpreter am Ende seiner Arbeit ja alles freigibt und beendet was irgendwie noch da bzw. offen ist).

    Oder du verwendest einen Logging-Daemon, der über Sockets oder Pipes Verbindungen annimmt, und alles was auf diesen Verbindungen ankommt in das Logfile schreibt. Der Logging-Daemon wäre dann wieder in etwas anderem als PHP implementiert, damit er asynchrone IO Funktionen, Threads und was nicht noch alles verwenden kann um das Schreiben von vielen kleinen Datenstückchen in ein gemeinsames Logfile zu beschleunigen.

    Jop, was dann wohl sowas wie Scribe wäre. Wenn ich das richtig verstanden habe.



  • Na ja, es würde ja schon was bringen, wenn der PHP-Logger pro Request nur einmal die Datei öffnen und schreiben würde. Natürlich müsste man dann aufpassen, dass die Datei nicht mehrfach gleichzeitig geöffnet ist. Da könnte man dann halt je nach Kollisionsmöglichkeiten pro Request eine File schreiben und das dann hin und wieder Mal mergen oder so... Nicht so chic, aber klappt php-only halt.


Anmelden zum Antworten