Thanks 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

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.