前段時間抽空寫了個微型路由控制器能夠在個人另外一篇文章裏面看到詳細的介紹。雖然在設計的時候及儘可能避開了正則匹配和數組循環這種耗時的操做。儘可能節省時間。可是那都是理論上的。今天就實際測試了一下。php
github上面專門有一個叫作php-router-benchmark的倉庫,用來測試路由分發的性能。git
上門有測試php-r3,Pux,FastRoute,Symfony2 Dumped,Symfony2 以及Aura v2這幾個路由控制器的性能,整體來講R3和FastRoute在最壞的狀況下表現最好。其中R3和Pux是C語言實現的插件,有語言上面的性能優點。github
首先fork了一份這個benchmark的庫,並把本身的Router的測試代碼加上去了。一樣的測試條件。因爲R3沒有裝上,還有Pux安裝失敗。因此本次測試僅僅針對FastRoute,Symfony2 Dumped,Symfony2,Aura v2以及Router。
這樣也好,反正這幾個都是純PHP實現的。另外兩個C語言實現的此次就不進行比較了。segmentfault
首先是最壞狀況下的測試,其中包含了兩個測試用例,一個是找不到的404 還有一個是在列表最後一個才能匹配到的,也就是最壞的兩種狀況。數組
This benchmark matches the last route and unknown route. It generates a randomly prefixed and suffixed route in an attempt to thwart any optimization. 1,000 routes each with 9 arguments.dom
This benchmark consists of 10 tests. Each test is executed 1,000 times, the results pruned, and then averaged. Values that fall outside of 3 standard deviations of the mean are discarded.ide
Test Name | Results | Time | + Interval | Change |
---|---|---|---|---|
Router - unknown route (1000 routes) | 993 | 0.0000232719 | +0.0000000000 | baseline |
Router - last route (1000 routes) | 981 | 0.0000955424 | +0.0000722705 | 311% slower |
FastRoute - unknown route (1000 routes) | 990 | 0.0005051955 | +0.0004819236 | 2071% slower |
FastRoute - last route (1000 routes) | 998 | 0.0005567203 | +0.0005334484 | 2292% slower |
Symfony2 Dumped - unknown route (1000 routes) | 998 | 0.0006116139 | +0.0005883420 | 2528% slower |
Symfony2 Dumped - last route (1000 routes) | 998 | 0.0007765370 | +0.0007532651 | 3237% slower |
Symfony2 - unknown route (1000 routes) | 996 | 0.0028456177 | +0.0028223458 | 12128% slower |
Symfony2 - last route (1000 routes) | 993 | 0.0030129542 | +0.0029896823 | 12847% slower |
Aura v2 - last route (1000 routes) | 989 | 0.1707107230 | +0.1706874511 | 733450% slower |
Aura v2 - unknown route (1000 routes) | 988 | 0.1798588730 | +0.1798356011 | 772760% slower |
查看上表的數據,我本身的Router在兩種測試用例的最壞狀況下都是表現最好的。而且把其餘幾個遠遠的甩出幾條街。看來這個主要得益於使用樹形結構的PHP數組來存儲路由表。因此進行遍歷的時候始終能達到O(log n)的時間複雜度。性能
而後再來看最好的狀況,也就是在第一個url就能匹配到的狀況。測試
This benchmark tests how quickly each router can match the first route. 1,000 routes each with 9 arguments.ui
This benchmark consists of 5 tests. Each test is executed 1,000 times, the results pruned, and then averaged. Values that fall outside of 3 standard deviations of the mean are discarded.
Test Name | Results | Time | + Interval | Change |
---|---|---|---|---|
FastRoute - first route | 998 | 0.0000498390 | +0.0000000000 | baseline |
Symfony2 Dumped - first route | 995 | 0.0000517531 | +0.0000019141 | 4% slower |
Router - first route | 994 | 0.0001499363 | +0.0001000972 | 201% slower |
Aura v2 - first route | 998 | 0.0008559464 | +0.0008061073 | 1617% slower |
Symfony2 - first route | 998 | 0.0012734995 | +0.0012236604 | 2455% slower |
查看這個表的數據,每個庫只有一個測試用例。是測試的「最好」的狀況。這裏之因此加上引號是由於,Router使用的是樹形結構存儲,其餘幾個庫所謂的「最好」狀況,其實不適用了。不能在第一個匹配到。因此應該說在這個測試用例中Router仍是以比較平均的時間來和其餘幾個庫的最好時間進行比較!!!(比較一下上下兩個表中的Time絕對值就能看出,其餘幾個庫在下面的「最好」狀況下都比上面的最壞狀況要好不少,可是Router庫的表現確是相反的,而且無論那種狀況時間都是比較接近的,這就和以前提到的樹形節點遍歷的時間複雜度相對固定有關係)
此次測試了幾個純PHP實現的路由控制器,等下次繼續把兩個C語言實現的庫一塊兒拿來比較一下!!!