3 ms·
As someone with a bit of experience scaling PHP, it seems to me that the main problem with the language is not its raw performance (which seems on a par with it
by loevborg 12y ago
As someone with a bit of experience scaling PHP, it seems to me that the main problem with the language is not its raw performance (which seems on a par with its more cousins Python and Ruby) but rather its single-request model. For every request, mod_php creates a new interpreter, which has to do all the work to set up the framework, auto-loading the required classes, reading additional data every time. What's more, the request has to create a new database connection for every request; the single-request model doesn't allow the use of a database pool. (This doesn't change fundamentally with handlers other than mod_php, such as php-fpm.)
With languages like Python and Ruby, not to mention Java, a single interpreter process or thread can handle many requests and can re-use the database connection. In PHP, you're forced to do all the set-up all over again for every request. This is particularly wasteful with frameworks like Laravel, which do a non-trivial amount of work for setting up the application object, IoC controller.
Am I missing something here? I can't believe companies using PHP on a larger scale, like Facebook, discard and re-create the application environment and all DB connections (!) for every single request.
- TazeTSchnitzel 12y agoI don't know about mod_php, but PHP can handle multiple requests in one process for some SAPIs. Also, opcode caching can improve things. Further, I think PHP's request model is a good thing. It makes web programming easier and makes PHP resistant against memory leaks.
- wolf550e 12y agoBut it's terrible for performance. The performance of trivial ajax requests is completely dominated by framework setup time, in my experience with Zend based code.
- yogo 12y agoWhat does the language have to do with framework setup? You can have horrible performance with any bloated framework setup. Trim the fat.
- mgkimsal 12y agoI think what the OP was getting at was that frameworks can be good - saving you a lot of DIY and building on (theoretically) good practices. But all that potential code reuse and possibly elegance is problematic in PHP because that has to be rebuilt on every single request. Arguably many Java frameworks are even more convoluted than, say, Zend Framework, but the Java platform means there's less of a performance price to pay for the bloat of a framework vs any PHP framework with similar 'bloat' (hierarchy of classes, etc). "Trim that fat" The "fat" is something which is useful to a lot of people for development, it's just a performance hindrance (and far moreso than in other platforms). That said, I've had some Java folks express some amazement at how fast PHP is, even when it's doing all the library loading and class instantiation on every page request. In multiple cases, they all expressed that they thought it would be far far slower, having grown used to "object creation is slow" in Java.
- Joeri 12y agoThat's why you should host using fastcgi, so the PHP processes are long lived. You do pay the startup cost in every request of reconstructing the state (code and session data), but you get the benefit of request isolation. I don't know how other db's handle it, but oracle supports reusing connections across PHP requests. Facebook does recreate the state on every request, but they've got that down to a 10 ms bootstrap. In my own web services the bootstrapping before the business logic runs is below 20 ms. Most PHP frameworks load too much code up front though, which is why you'll see much worse request bootstrap performance in many cases. The big benefit of request isolation is predictability. You know exactly what environment your code runs in because you construct it from scratch for every request.
- delinka 12y ago"You do pay the startup cost in every request of reconstructing the state..." And I thought this was the very "problem" that drove people away from CGIs back in the day.
- Joeri 12y agoIt's not a problem, it's a trade-off. An architecture that doesn't keep state across requests trades off per-request performance for stability and scalability, because there is no long-term state on the web server to manage or migrate. CGI traded off too much performance because of the need to launch a process per request, but fastcgi keeps the process alive but throws away the state, so i find the upside beats the downside in a lot of cases (sadly not all, i wish php was less opinionated here, like java where you can choose to have a stateless architecture but don't have to.)
- shivaas 12y agoare you using a custom PHP framework to get your bootstrap below 20ms ? would like to hear more about your stack setup to get that kind of performance
- Joeri 12y agoI have to admit our architecture is unconventional. It's custom code except for a few ZF1 parts like zend_db, zend_json_service and zend_validate. Even our session and auth code is all custom. The server we use is zend server (with zend opcache). We only have web services on the server, it's a javascript ui. The web service wrapper on the server has been cut down to the essence and does not use autoloading for the basic bootstrap. I've found that the PSR approach of a gazillion files each containing a small class and liberal use of autoloading is inherently slow, it is death by a thousand paper cuts due to the high degree of file access, memory consumption and running of all that constructor code. The code i write typically groups a web service in a handful of files, each containing a namespace with the bulk of the implementation in procedural logic (though i do use closures quite a bit). I typically use classes / objects only as types that encapsulate data, with the logic on the object limited to that logic which is necessary for working with that type (e.g. I don't put a save method on an object but instead write a saveObject function which accepts the object as a parameter and passes back an array of errors). I suppose a lot of people nowadays find that sort of coding style blasphemous, but it is easy to write, test and maintain, and fast to execute. I'm not against the heavy OO approach common in most web dev nowadays, there are times when i do use it and need it. But CRUD web services are very linear: validate the input, create a transaction, run a bunch of db operations, commit or roll back, and return status / errors. If something is linear, i prefer to see it implemented in a cohesive linear procedural style, instead of getting chopped up into lots of objects that in practice end up obfuscating what's happening.