12 ms·
Pux – High Performance Router for PHP
- ComSubVie 13y agoIt's nice to see a PHP extension for routing to improve performance, but is it really necessary to compile the routing definition before being able to use it?
- jbeja 13y agoNice, a long time has passed since i saw a PHP project HN.
- shocks 13y agoThey're about, but 99% of the time they're flagged/reported because "PHP SUCKS YO!".
- CharlesW 13y agoIf the creators are watching, I think it'd be interesting to benchmark against the current Respect/Rest.
- fooyc 13y ago> Pux tries not to consume computation time to build all routes dynamically (like Symfony/Routing). Instead, Pux compiles your routes to plain PHP array for caching, the compiled routes can be loaded from cache very fast. symfony/routing compiles routes only once to PHP code ([1]), and then that generated code is used for matching all subsequent requests. (There are multiple route matchers, but the default one works like this.) It's amazing that Pux manages to be close to 50x times faster. How is this achieved ? [1] https://github.com/symfony/Routing/blob/0ee25e6580bd4169c1289bdcbefa22220a3a4a8f/Tests/Fixtures/dumper/url_matcher1.php#L23 https://github.com/symfony/Routing/blob/0ee25e6580bd4169c128...
- mjburgess 13y agoWell for a start they're misusing apachebench gnuplot data (which isnt time-ordered). And "compiled to php" is kinda meaningless, it depends what it's compiled to. There is no "native routing" language. For my two cents, if you're having to translate your solution into simpler code your solution is wrong.
- fooyc 13y agoAs always, it depends
- cdekok 13y agoProbably by the php extension in c :) I would think that phalcon router will be faster too.
- daGrevis 13y agoBecause routing is the bottleneck.
- agumonkey 13y agoSometimes complex webapps in symfony can spend a significant amount of time in routing, probably not critical but well, why not lessen it.
- esailija 13y agoYou can gain ridiculous performance improvements without anything ever really being a bottleneck at all - this attitude is wrong and annoying.
- tbarbugli 13y agoIndeed ;)
- deleted 13y ago[deleted]
- randomdrake 13y agoThanks for your contribution! Always love seeing new attempts with PHP. While I 100% appreciate your efforts, there are a few really big questions or problems I have with the way this has been presented. As a PHP developer, I hope you don't mind me addressing them here. 1) You benchmarked a large framework with all sorts of features and functionality against a very specific library with a few files. What about all of the extra pieces from Symfony? What do those files bring to the table or don't they? Did you only test routing features? If so, how? Are all of the features from that Symfony package available in Pux? 2) The title of the graphs showing the hockey stick effect you were undoubtedly looking for is: ab -n 1000 -c 10 The graphs seem to go to 2000. In looking at your test files in your repo, we see the following: ab -g out.dat -n 2000 -c 10 http://localhost/work/php/symfony-routing-example/index.php http://localhost/work/php/symfony-routing-example/index.php When creating benchmarks, accuracy and transparency is an absolute must. That aside: looking at the graphs, it's clear there isn't much of a difference at the 1000 level. Boosting that to 2000 appears to have had your desired effect. But what's the reason for it and why does it change? Also, a concurrency of 10? Why 10? What about 1? 50? 100? 1000? Does it never fail? Does it only work well around 10 concurrent users? Making massive claims requires massive evidence. 3) You're comparing apples to oranges here. To get to the point you're at in your test, requires a user to install an extension and run a file on the server to compile the routes, every time the routes change. Symfony doesn't require this. "Pux tries not to consume computation time to build all routes dynamically (like Symfony/Routing). Instead, Pux compiles your routes to plain PHP array for caching, the compiled routes can be loaded from cache very fast." To get the performance you're wanting, no, Pux doesn't do it dynamically. Which, makes sense because it's writing a flat file to disk and calling it "compiling" or "caching" when it really isn't either in the traditional sense. You can tell it to write a file to disk of the rendered routes, but it must be manually told to do so; unless I'm missing something in the code, it does not happen automatically. Without reading in the file to check for differences, it couldn't. The performance would almost certainly degrade. Moving bottleneck concerns to a different layer of the application and then specifically benchmarking against that is almost certainly going to give you the benchmarks you're looking for. Since you have moved your concerns to your disk, you now run into all sorts of problems that come along with such a philosophy. How do you ensure the same file is split across multiple servers? Who has access to run the script necessary to create the file? What happens if the application grows so big that the file can't reasonably fit into memory? What happens when disk reading and writing becomes too expensive? Y'know, the regular questions that crop up when you start to move performance concerns to disk. This would be much more accurate, and in my opinion interesting, if it left off the comparison to Symfony completely, stopped using words like "compile" and "cache," and instead described it by saying what it actually does: Pux is a library with an extension for fast tokenization and rendering of strings for application routing and a set of files to allow the option of writing those renderings to disk instead of having them executed at runtime.
- rdlowrey 13y agoThe problem with this is you can accomplish essentially the same thing in userland if you know how to write a good "compiled regex" ... Calling the pcre functions in C land gains you very little. An extension is totally unnecessary.
- pedro93 13y agoI don't think so. Using pure PHP, you need to load a lot of class files. and function calls, method calls, hash find are pretty slow in pure PHP. - First of all, while using C extension, you don't need to reload these php class files again and again. it reduces the class loading overhead. - Seconds, looping and string comparison is pretty fast in C. it's because in pure PHP, it duplicates the string when calling functions/methods in the runtime. - Third, there are a lot of spaces to optimize the code in C rather than in pure php. - Last, pure PHP consumes a lot of memory, but in C extension, the memory footprint is pretty small.
- abcd_f 13y agoIf they would only first explain what the heck is "routing in PHP"... Coming from the network programming side of things, "High Performance PHP Router" sounds like a spectacular oxymoron at best :)
- rdlowrey 13y agoI agree ... many PHP devs seem to think that programming only exists between when the web server gives a request to a PHP process and when that process closes it's STDOUT handle to complete the response.
- Gigablah 13y agoWhy PHP devs? Aren't "routing" libraries also available in other popular languages with frameworks? Are those devs somehow beyond reproach?
- itafroma 13y ago> If they would only first explain what the heck is "routing in PHP"... "Routing" is a common and well-understood term in application development: I'm sure you can appreciate the act of writing documentation for an intended audience. In the context of an application, a router interprets a request from a client and forwards it to the appropriate resource (a controller or some other business logic) which then produces a response.
- sixthloginorso 13y agoWeb application development. I'm sure plenty of programmers would think of the Layer-3 device that chooses paths to forward packets through nodes to a destination.
- jkrems 13y ago> writing documentation for an intended audience Yes, and web application developers are the intended audience.
- 13y ago
- aw3c2 13y agoYour requests per second chart https://raw.github.com/c9s/Pux/master/benchmarks/reqs.png https://raw.github.com/c9s/Pux/master/benchmarks/reqs.png is a perfect example of a misleading chart, some even might call it lying. Please use 0 as the baseline (zero point of y axis).
- nodesocket 13y agoNot sure the performance difference, but highly recommend Flight (http://flightphp.com/ http://flightphp.com/) as a simple router. Flight is well suited especially for building APIs. Flight has great http helper methods as well (header, json response, etc). As far as performance, I seriously doubt the bottleneck in modern applications is the router.
- pedro93 13y agowell, flight is not written in C extension. have checked the code, there are a lot of magic method calls in flightphp. magic method calls are even slower than normal method call.
- giusc 13y agoMy personal opinion is that either no symfony and no pux should exist. There's no need to reinvent frameworks in PHP as PHP is the framework already. There's no need to reinvent templating in PHP as PHP is the templating already. If you require different productivity from a language just don't stick on PHP and make the right choice by using the most appropriate language for you. There's plenty out there. PHP is great, it rocks and is very fast when used in the right way.
- icedchai 13y agoExactly. You don't need a 'router' when you have the filesystem and mod_rewrite.
- p4lindromica 13y agoWhat about when you are deploying with PHP-FPM or HipHopVM? A native routing component separates your application from your application server.
- icedchai 13y agoUsing mod_rewrite (or the nginx equivalent) with PHP-FPM will work fine. I don't see why it wouldn't work with HipHopVM either. In over 10+ years of PHP development I have never needed a "native routing component". Call me crazy...
- aethr 13y agoIf you're building a web application in PHP, then symfony is a huge improvement over naked php files or rolling your own bootstrapped system. Right out of the box it addresses concerns of security, user management, routing, persistence, and myriads of the other basic needs of a web system. Packages for many common components are already built, meaning you can get sophisticated functionality working quickly. It is modular enough that you can include only the components you need. The built-in templating language, twig, actually provides a number of benefits over bare PHP templating. It addresses security concerns, has a concise and clean syntax, and compiles down to optimised PHP template code, minimising the performance hit. If you are suggesting that PHP shouldn't be used for web applications, and should only be used for basic templating, I would be interested to know what you consider to be an "appropriate language".
- elwell 13y agoI've never thought of routing being an area in need of optimization, but hey.
- elwell 13y agoFastest routing is: http://domain.com/filename.php?args http://domain.com/filename.php?args
- noodlehaus 13y agoyou can use this -- http://github.com/noodlehaus/flat http://github.com/noodlehaus/flat
- pedro93 13y agoFirst of all, for your information, the benchmark code and details are already there: https://github.com/c9s/router-benchmark https://github.com/c9s/router-benchmark sorry I forgot to put the link. :p We firstly tested the pure dispatching benchmark by a simple benchmark tool. (without ab), code is here. https://github.com/c9s/router-benchmark/blob/master/code/dispatch.php https://github.com/c9s/router-benchmark/blob/master/code/dis... Tests including klein, ham, aura, symfony/routing. This tests pure dispatching speed, so the benchmark does not includes cache. The dispatching benchmark result is here: https://github.com/c9s/router-benchmark/blob/master/code/dispatch.txt https://github.com/c9s/router-benchmark/blob/master/code/dis... The benchmark with apache is just to show the comparison result (which shares the same configurations). Pux is basically written in C extension, which reduces the overhead to load classes from PHP files. Also it does a different strategy on route dispatching. to compare the routes as fast as possible, pux uses indexed array to store the route pattern, pcre flag. (In PHP internals, zend_hash_index_find is faster than zend_hash_find) it's not just iterating all routes in a big loop like Symfony.
- Gigablah 13y ago> it's not just iterating all routes in a big loop like Symfony. Well, that happens if you turn off the cache. Otherwise, Symfony actually compiles the routes into something resembling a prefix tree.
- WTFPL 13y agoWasn't there very similar project published a week or so ago? Just can't remember the name of it.