├── LICENSE ├── README.md ├── basic ├── README.md ├── apache.php └── swoole.php ├── basic_class_load ├── README.md ├── apache.php └── swoole.php ├── basic_class_load_multiple ├── README.md ├── apache.php └── swoole.php ├── basic_query ├── README.md ├── apache.php └── swoole.php ├── basic_query_with_pool ├── README.md ├── apache.php └── swoole.php ├── basic_query_with_pool_and_caching ├── README.md ├── apache.php └── swoole.php ├── include ├── available_classes.php ├── conn_settings.php └── functions.php ├── real_app_simulation ├── README.md ├── apache.php └── swoole.php ├── real_app_simulation_with_files ├── README.md ├── apache.php └── swoole.php ├── real_app_simulation_with_files_and_connections ├── README.md ├── apache.php └── swoole.php ├── real_app_simulation_with_files_and_connections_simpler ├── README.md ├── apache.php └── swoole.php ├── results ├── combined_chart.png ├── graph_requests_100.png ├── graph_requests_1000.png ├── graph_requests_500.png ├── results.ods ├── results_requests_100.ods ├── results_requests_1000.ods └── results_requests_500.ods ├── simple_real_app_simulation ├── README.md ├── apache.php └── swoole.php ├── test_db_dump.sql └── zend_framework └── composer.json /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2019, Vesko Kenashkov 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Swoole performance tests and comparisons 2 | 3 | **[JUMP TO AGGREGATED RESULTS AND GRAPHS](https://github.com/kenashkov/swoole-performance-tests#aggregated-results-and-graphs)** 4 | 5 | ## Introduction 6 | 7 | Performance tests of [Swoole](https://www.swoole.co.uk/) against other PHP application server setups. Most of the tests are cumulative - meaning they include everything from the previous and add more. 8 | 9 | Apache `ab` (ApacheBench, Version 2.3 <$Revision: 1430300 $>) is used for the tests. The non-informational and repeating part is cut and replaced with [...] in the outputs. 10 | 11 | Most tests are run with 100 requests per second (concurrency) and 10 000 requests (denoted 100 / 10 000 in the results), 500 / 10 000 and 1 000, and 10 000 (whenever possible/practical due to the high load). 12 | KeepAlive is also used on all tests (-k). 13 | 14 | As there is some cache related variance tor every test two runs are done and the highest one is taken. 15 | 16 | These tests are attempt to show different aspects of Swoole and also a comparison between Swoole and Apache/mod_php in tests close to real world applications. 17 | 18 | Please create a **Pull Request** if you think there is a mistake or there is a test you would like to add or more tuning to either Swoole or Apache that could/should be done. 19 | 20 | **[JUMP TO AGGREGATED RESULTS AND GRAPHS](https://github.com/kenashkov/swoole-performance-tests#aggregated-results-and-graphs)** 21 | 22 | ## Source code 23 | 24 | The below are given all the files needed to repeat the test. 25 | 26 | - [PHP test files](https://github.com/kenashkov/swoole-performance-tests/) 27 | - [MySQL dump](https://github.com/kenashkov/swoole-performance-tests/blob/master/test_db_dump.sql) - needed for the test connection 28 | - [MySQL connection settings](https://github.com/kenashkov/swoole-performance-tests/blob/master/conn_settings.php) - need to be updated in this file 29 | - [Docker images](https://hub.docker.com/r/kenashkov/php-tests) 30 | - [Dockerfiles](https://github.com/kenashkov/php-tests-dockerfiles) 31 | - [Zend Framework](https://framework.zend.com/downloads) - to be installed under ./zend_framework with `composer require zendframework/zendframework` for test purpose 32 | 33 | The tests were done on: 34 | ``` 35 | Swoole container: PHP 7.3.10 & Swoole 4.4.10 (note - at the time of writing this is not yet officially released, the build was done on 31st Oct 2019) 36 | Apache/mod_php container: Apache 2.4.25 & PHP 7.3.10 37 | Intel(R) Xeon(R) CPU X5690 @ 3.47GHz - 6 physical cores, 12MB cache 38 | Multithreading enabled - 12 cores 39 | 24 GB RAM 40 | Swoole running with 24 workers 41 | Apache running in Prefork tuned for many concurrent connections as per https://oxpedia.org/wiki/index.php?title=Tune_apache2_for_more_concurrent_connections 42 | 43 | ServerLimit 250 44 | StartServers 10 45 | MinSpareThreads 75 46 | MaxSpareThreads 250 47 | ThreadLimit 64 48 | ThreadsPerChild 32 49 | MaxRequestWorkers 8000 50 | MaxConnectionsPerChild 10000 51 | 52 | Swoole is running with 24 workers (and 5 DB connections per Worker in the DB Pools whenever this is applicable) 53 | ``` 54 | 55 | The MySQL instance used for testing is MySQL 8 on another host in the same network with connection limit of 4000. 56 | 57 | ## Tests and results 58 | 59 | A list of the test - **please click on each test for more details** and complete `ab` output: 60 | - [1] **[basic](./basic/)** - a "hello world" test 61 | - Swoole 100 / 10 000 - Requests per second: **66308.60** 62 | - Apache/mod_php 100 / 10 000 - Requests per second: **25705.82** (see note - **1846.98**) 63 | - Swoole 500 / 10 000 - Requests per second: **59658.75** 64 | - Apache/mod_php 500 / 10 000 - Requests per second: **1846.98** with **251 failed requests** 65 | - Swoole 1 000 / 10 000 - Requests per second: **34923.27** 66 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **1499.39** with **182 failed requests** 67 | - [2] **[basic_class_load](./basic_class_load/)** - [basic](./basic/) + contains 2 require_once() statements 68 | - Swoole 100 / 10 000 - Requests per second: **52451.86** 69 | - Apache/mod_php 100 / 10 000 - Requests per second: **11559.91** 70 | - Swoole 500 / 10 000 - Requests per second: **41044.00** 71 | - Apache/mod_php 500 / 10 000 - Requests per second: **1706.33** with **144 failed requests** 72 | - Swoole 1 000 / 10 000 - Requests per second: **34662.77** 73 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **1339.36** with **161 failed requests** 74 | - [3] **[basic_class_load_multiple](./basic_class_load_multiple/)** - [basic_class_load](./basic_class_load/) + autoloading (through Composer autoload) 100 classes 75 | - Swoole 100 / 10 000 - Requests per second: **53625.63** 76 | - Apache/mod_php 100 / 10 000 - Requests per second: **2073.61** 77 | - Swoole 500 / 10 000 - Requests per second: **39887.20** 78 | - Apache/mod_php 500 / 10 000 - Requests per second: **1010.27** with **187 failed requests** 79 | - Swoole 1 000 / 10 000 - Requests per second: **35451.69** 80 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **1016.76** with **238 failed requests** 81 | - [4] **[basic_query](./basic_query/)** - a single DB query 82 | - Swoole 100 / 10 000 - Requests per second: **1804.08** 83 | - Apache/mod_php 100 / 10 000 - Requests per second: **1314.86** 84 | - Swoole 5000 / 10 000 - Not performed (due to number of DB connection) 85 | - Apache/mod_php 5000 / 10 000 - Not performed (due to number of DB connections) 86 | - Swoole 1 000 / 10 000 - Not performed (due to number of DB connection) 87 | - Apache/mod_php 1 000 / 10 000 - Not performed (due to number of DB connections) 88 | - [5] **[basic_query_with_pool](./basic_query_with_pool/)** - [basic_query](./basic_query/) + connection pooling (in Apache this is using persistent connections) 89 | - Swoole 100 / 10 000 - Requests per second: **4163.17** 90 | - Apache/mod_php 100 / 10 000 - Requests per second: **2327.34** 91 | - Swoole 500 / 10 000 - Requests per second: **4279.57** 92 | - Apache/mod_php 500 / 10 000 - Requests per second: **1059.98** with **228 failed requests** 93 | - Swoole 1 000 / 10 000 - Requests per second: **4326.38** 94 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **failed, 9547 requests completed** 95 | - [6] **[basic_query_with_pool_and_caching](./basic_query_with_pool_and_caching)** - reading cashed results (the query matters only for the first read so does not really rely on basic_query_with_pool) 96 | - Swoole 100 / 10 000 - Requests per second: **53499.11** 97 | - Apache/mod_php 100 / 10 000 - Requests per second: **25141.67** (note: many tests are in the range of 1900-2000) 98 | - Swoole 500 / 10 000 - Requests per second: **41790.99** 99 | - Apache/mod_php 500 / 10 000 - Requests per second: **1831.16** with **237 failed requests** 100 | - Swoole 1 000 / 10 000 - Requests per second: **38591.86** 101 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **1535.84** with **107 failed requests** 102 | - [7] **[real_app_simulation](./real_app_simulation/)** - [basic_class_load_multiple](./basic_class_load_multiple/) + 10 000 cache reads 103 | - Swoole 100 / 10 000 - Requests per second: **15195.12** 104 | - Apache/mod_php 100 / 10 000 - Requests per second: **228.51** 105 | - Swoole 500 / 10 000 - Requests per second: **15771.75** 106 | - Apache/mod_php 500 / 10 000 - Requests per second: **197.57** with **153 failed requests** 107 | - Swoole 1 000 / 10 000 - Requests per second: **14635.35** 108 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **failed, 1266 requests completed** 109 | - [8] **[real_app_simulation_with_files](./real_app_simulation_with_files/)** - [real_app_simulation_with_files](./real_app_simulation_with_files/) + 10 file writes and 10 file reads 110 | - Swoole 100 / 10 000 - Requests per second: **845.97** 111 | - Apache/mod_php 100 / 10 000 - Requests per second: **220.27** 112 | - Swoole 500 / 10 000 - Requests per second: **1372.28** 113 | - Apache/mod_php 500 / 10 000 - Requests per second: **196.54** with **222 failed requests** 114 | - Swoole 1 000 / 10 000 - Requests per second: **1426.92** 115 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **failed, 1339 requests completed** 116 | - [9] **[real_app_simulation_with_files_and_connections](./real_app_simulation_with_files_and_connections/)** - [real_app_simulation_with_files](./real_app_simulation_with_files/) + 20 DB reads (pooled connection) 117 | - Swoole 100 / 10 000 - Requests per second: **285.91** 118 | - Apache/mod_php 100 / 10 000 - Requests per second: **141.24** 119 | - Swoole 500 / 10 000 - Requests per second: **285.32** 120 | - Apache/mod_php 500 / 10 000 - Requests per second: **115.82** with **249 failed requests** 121 | - Swoole 1 000 / 10 000 - Requests per second: **314.33** 122 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **failed, 1159 requests completed** 123 | - [10] **[real_app_simulation_with_files_and_connections_simpler](./real_app_simulation_with_files_and_connections_simpler/)** - [real_app_simulation_with_files_and_connections](./real_app_simulation_with_files_and_connections/) but with less loaded classes and cache/file/db reads 124 | - Swoole 100 / 10 000 - Requests per second: **1919.86** 125 | - Apache/mod_php 100 / 10 000 - Requests per second: **1194.24** 126 | - Swoole 500 / 10 000 - Requests per second: **1824.30** 127 | - Apache/mod_php 500 / 10 000 - Requests per second: **723.21** with **244 failed requests** 128 | - Swoole 1 000 / 10 000 - Requests per second: **1956.75** 129 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **702.33** with **256 failed requests** 130 | - [11] **[simple_real_app_simulation](./simple_real_app_simulation)** - 1000 reads from cache, loads 100 classes and performs 2 fast DB queries. 131 | - Swoole 100 / 10 000 - Requests per second: **2288.58** 132 | - Apache/mod_php 100 / 10 000 - Requests per second: **1250.36** 133 | - Swoole 500 / 10 000 - Requests per second: **2011.11** 134 | - Apache/mod_php 500 / 10 000 - Requests per second: **774.52** with **196 failed requests** 135 | - Swoole 1 000 / 10 000 - Requests per second: **2228.23** 136 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **failed with 7702 completed requests** 137 | 138 | ## Aggregated results and Graphs 139 | 140 | The given graphs show just the number of served requests per second but do not show the number of failed requests (these are shown in the table and "All results" file given below). 141 | 142 | #### All requests graph 143 | ![](https://github.com/kenashkov/swoole-performance-tests/blob/master/results/combined_chart.png) 144 | 145 | #### concurrency 100 / requests 10 000 graph 146 | ![](https://github.com/kenashkov/swoole-performance-tests/blob/master/results/graph_requests_100.png) 147 | 148 | #### concurrency 500 / requests 10 000 graph 149 | ![](https://github.com/kenashkov/swoole-performance-tests/blob/master/results/graph_requests_500.png) 150 | 151 | #### concurrency 1 000 / requests 10 000 graph 152 | ![](https://github.com/kenashkov/swoole-performance-tests/blob/master/results/graph_requests_1000.png) 153 | 154 | #### Requests per second and failed requests 155 | 156 | 157 | | | Swoole 100 \# reqs/sec | Swoole 100 \# failed reqs | Apache/mod\_php 100 \# reqs/sec | Apache/mod\_php 100 \# failed reqs | Swoole 500 \# reqs/sec | Swoole 500 \# failed reqs | Apache/mod\_php 500 \# reqs/sec | Apache/mod\_php 500 \# failed reqs | Swoole 1000 \# reqs/sec | Swoole 1000 \# failed reqs | Apache/mod\_php 1000 \# reqs/sec | Apache/mod\_php 1000 \# failed reqs | 158 | |---------------------------------------------------------------|------------------------|---------------------------|---------------------------------|------------------------------------|------------------------|---------------------------|---------------------------------|------------------------------------|-------------------------|----------------------------|----------------------------------|-------------------------------------| 159 | | basic | 66308\.6 | 0 | 25705\.82 | 0 | 59658\.75 | 0 | 1846\.98 | 251 | 34923\.27 | 0 | 1499\.39 | 182 | 160 | | basic\_class\_load | 52451\.86 | 0 | 11559\.91 | 0 | 41044 | 0 | 1706\.33 | 144 | 34662\.77 | 0 | 1339\.36 | 161 | 161 | | basic\_class\_load\_multiple | 53625\.63 | 0 | 2073\.61 | 0 | 39887\.2 | 0 | 1010\.27 | 187 | 35451\.69 | 0 | 1016\.76 | 238 | 162 | | basic\_query | 1804\.08 | 0 | 1314\.86 | 0 | NA | NA | NA | NA | NA | NA | NA | NA | 163 | | basic\_query\_with\_pool | 4163\.17 | 0 | 2327\.34 | 0 | 4279\.57 | 0 | 1059\.98 | 228 | 4326\.38 | 0 | FAILED | FAILED | 164 | | basic\_query\_with\_pool\_and\_caching | 53499\.11 | 0 | 25141\.67 | 0 | 41790\.99 | 0 | 1831\.16 | 237 | 38591\.86 | 0 | 1535\.84 | 107 | 165 | | real\_app\_simulation | 15195\.12 | 0 | 228\.51 | 0 | 15771\.75 | 0 | 197\.57 | 153 | 14635\.35 | 0 | FAILED | FAILED | 166 | | real\_app\_sim\_with\_files | 845\.97 | 0 | 220\.27 | 0 | 1372\.28 | 0 | 196\.54 | 222 | 1426\.92 | 0 | FAILED | FAILED | 167 | | real\_app\_sim\_with\_files\_and\_conn | 285\.91 | 0 | 141\.24 | 0 | 285\.32 | 0 | 115\.82 | 249 | 314\.33 | 0 | FAILED | FAILED | 168 | | real\_app\_sim\_with\_files\_and\_conn\_simpler | 1919\.86 | 0 | 1194\.24 | 0 | 1824\.3 | 0 | 723\.21 | 244 | 1956\.75 | 0 | 702\.33 | 256 | 169 | | simple\_real\_app\_simulation | 2288\.58 | 0 | 1250\.36 | 0 | 2011\.11 | 0 | 774\.52 | 196 | 2228\.23 | 0 | FAILED | FAILED | 170 | 171 | #### Requests per second only 172 | 173 | | | Swoole 100 \# reqs/sec | Apache/mod\_php 100 \# reqs/sec | Swoole 500 \# reqs/sec | Apache/mod\_php 500 \# reqs/sec | Swoole 1000 \# reqs/sec | Apache/mod\_php 1000 \# reqs/sec | 174 | |---------------------------------------------------------------|------------------------|---------------------------------|------------------------|---------------------------------|-------------------------|----------------------------------| 175 | | basic | 66308\.6 | 25705\.82 | 59658\.75 | 1846\.98 | 34923\.27 | 1499\.39 | 176 | | basic\_class\_load | 52451\.86 | 11559\.91 | 41044 | 1706\.33 | 34662\.77 | 1339\.36 | 177 | | basic\_class\_load\_multiple | 53625\.63 | 2073\.61 | 39887\.2 | 1010\.27 | 35451\.69 | 1016\.76 | 178 | | basic\_query | 1804\.08 | 1314\.86 | NA | NA | NA | NA | 179 | | basic\_query\_with\_pool | 4163\.17 | 2327\.34 | 4279\.57 | 1059\.98 | 4326\.38 | FAILED | 180 | | basic\_query\_with\_pool\_and\_caching | 53499\.11 | 25141\.67 | 41790\.99 | 1831\.16 | 38591\.86 | 1535\.84 | 181 | | real\_app\_simulation | 15195\.12 | 228\.51 | 15771\.75 | 197\.57 | 14635\.35 | FAILED | 182 | | real\_app\_sim\_with\_files | 845\.97 | 220\.27 | 1372\.28 | 196\.54 | 1426\.92 | FAILED | 183 | | real\_app\_sim\_with\_files\_and\_conn | 285\.91 | 141\.24 | 285\.32 | 115\.82 | 314\.33 | FAILED | 184 | | real\_app\_sim\_with\_files\_and\_conn\_simpler | 1919\.86 | 1194\.24 | 1824\.3 | 723\.21 | 1956\.75 | 702\.33 | 185 | | simple\_real\_app\_simulation | 2288\.58 | 1250\.36 | 2011\.11 | 774\.52 | 2228\.23 | FAILED | 186 | 187 | Thanks to [tableconvert.com](https://tableconvert.com/) 188 | 189 | #### Result files in ODS format 190 | - [All results](https://github.com/kenashkov/swoole-performance-tests/blob/master/results/results.ods) 191 | - [Results 100 concurrency](https://github.com/kenashkov/swoole-performance-tests/blob/master/results/results_requests_100.ods) 192 | - [Results 500 concurrnecy](https://github.com/kenashkov/swoole-performance-tests/blob/master/results/results_requests_500.ods) 193 | - [Results 1 000 concurrency](https://github.com/kenashkov/swoole-performance-tests/blob/master/results/results_requests_1000.ods) 194 | 195 | ## Conclusion 196 | 197 | Performance conclusions: 198 | - based on test [1] Swoole is twice as fast as Apache/mod_php in handling connections and returning response. 199 | - based on tests [2] and [3] it is clear the advantage Swoole has when loading php files/classes - it is done only once before server start. 200 | - based on tests [4] and [5] we can say that if the persistent connections are not used Swoole has clear advantage. When persistent connections are used Swoole is around twice faster - the result from test [1]. 201 | The persistent connections in PHP need to be very well controlled as otherwise they can take up to the maximum allowed by the DB. 202 | In Swoole it is very easy to control the number of the connections in the Pool. They are the product of the number of Workers and the number of allocated connections per pool. In our tests this is 24 workers * 5 connections = 120. 203 | - test [7] shows the expected - Swoole is king in caching as it can use the local PHP memory for that. 204 | - tests [8] and [9] simulate load closer to a real world application. Here Swoole coroutines and persistent memory give the advantage. The drop in the performance of Swoole in [9] is due to the SLEEP(0.01) in the query. This is expected and is put here to show that in applications where the slowest part are the DB queries by just running these on Swoole will not improve much the performance. 205 | What will improve the performance in this case is to run some (most if possible) of the queries in parallel by using sub-coroutines. This is possible only if the queries are independent of each other. 206 | Also both these tests show more requests served under higher load - this I attribute to the async operations performed in these tests and Swoole relying on the coroutines for these. 207 | - test [10] is a simpler version of [9] and it repeats its results 208 | - test [11] is just a representation of what a real world Swoole application should aim to be - use as much as possible caching and few IO operations. The amount of loaded classes does not affect the performance. 209 | 210 | Overall conclusion: 211 | - in simple applications or microservices Swoole will excel as these will be mostly cached. Swoole leads here as it loads the classes only once and can use memory for all the caching. 212 | - In more complex applications the difference between Swoole and Apache/mod_php is about 1.8-2 times - this is due to the fact that the speed is greatly reduced by the IO operations. Swoole is still more efficient here due to the coroutines. 213 | If the application can be optimized to use caching as much as possible Swoole will perform better as there is no serialization/unserialization and access to external storage (be it even shared memory access). 214 | An app/service that uses mostly caching and perhaps a single fast read IO operation can be scaled to 4-5 000 requests per second. 215 | If there are no IO operations (for example Swoole\Table can be used for sharing data between the Workers) then the requests can reach 10-20 000 per second (test [6] shows 53 000 but this drops when there is actual business logic to be executed). 216 | - Swoole can serve more requests than Apache and there was no a single failed request in all the tests. 217 | - Swoole is a step further both in speed and the load that can be sustained compared to Apache/mod_php 218 | 219 | Swoole does not execute PHP faster that any other setup. If your application uses heavy processing in PHP it will not benefit that much if you switch to Swoole. 220 | 221 | Swoole can also serve as a traditional web server (static_handler & document_root need to be enabled) but it is better to offload the static handling to Apache or Nginx. 222 | Swoole also supports HTTP2 and HTTPS but these were not included in the tests. And there is also a Websocket server! 223 | 224 | One last thing to note is that the tests were done on a 6 core processor. Modern servers are usually dual socket and have 8-10 cores per socket so the actual results if you run the same tests on your server will be better. 225 | Of course running real world application will produce different results. 226 | 227 | ## Additional resources 228 | 229 | - [English documentation](http://swoole.co.uk) - some parts of the documentation are outdated. 230 | - [Chinese documentation](https://wiki.swoole.com/) - Google Translate does a decent job and I strongly recommend this resource. Besides current documentation there are also many technical details/advanced sections provided. 231 | - [Coroutines in Swoole](http://vesko.blogs.azonmedia.com/2019/09/19/coroutines-in-swoole/) - Introduction to Coroutines in Swoole. 232 | 233 | ## Edits 234 | - 19.12.2019 - fixed docker images links and some typos 235 | -------------------------------------------------------------------------------- /basic/README.md: -------------------------------------------------------------------------------- 1 | # Basic test 2 | 3 | This is a purely synthetic test returning "OK" output. 4 | As these tests go the produced output is not relevant to real world application. 5 | 6 | In this test run Apache/mod_php on 100 / 10 000 shows a great variance in the results. It seems cache/memory related and sometimes it seves 20 000+ requests per second, while most of the times it is about 2000 per second. 7 | It is to note that in the next test Apache gies persistent 11-12k requests per second so for this test I take the 25705 value as achievable. 8 | But again - this test reflects no real world application so these results are not of such importance. 9 | 10 | The results are: 11 | - Swoole 100 / 10 000 - Requests per second: **66308.60** 12 | - Apache/mod_php 100 / 10 000 - Requests per second: **25705.82** (see note above - **1846.98**) 13 | - Swoole 500 / 10 000 - Requests per second: **59658.75** 14 | - Apache/mod_php 500 / 10 000 - Requests per second: **1846.98** with **251 failed requests** 15 | - Swoole 1 000 / 10 000 - Requests per second: **34923.27** 16 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **1499.39** with **182 failed requests** 17 | 18 | This test just gives an indication that Swoole is overall twice faster serving simple requests. 19 | This result will be affected if a large class codebase is being loaded - Swoole does this only once, while Apache/mod_php has to load the files on every request (even with Opcache enabled) so in this case Apache/mod_php will be a little slower. 20 | This shortcoming will be addressed in PHP 7.4 (see [Preloading RFC](https://wiki.php.net/rfc/preload)). 21 | 22 | 23 | #### Swoole with 100 / 10 000 24 | ``` 25 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://localhost:8082/ 26 | 27 | [...] 28 | 29 | Server Software: swoole-http-server 30 | Server Hostname: localhost 31 | Server Port: 8082 32 | 33 | Document Path: / 34 | Document Length: 2 bytes 35 | 36 | Concurrency Level: 100 37 | Time taken for tests: 0.151 seconds 38 | Complete requests: 10000 39 | Failed requests: 0 40 | Write errors: 0 41 | Keep-Alive requests: 10000 42 | Total transferred: 1540000 bytes 43 | HTML transferred: 20000 bytes 44 | Requests per second: 66308.60 [#/sec] (mean) 45 | Time per request: 1.508 [ms] (mean) 46 | Time per request: 0.015 [ms] (mean, across all concurrent requests) 47 | Transfer rate: 9972.19 [Kbytes/sec] received 48 | 49 | Connection Times (ms) 50 | min mean[+/-sd] median max 51 | Connect: 0 0 0.4 0 6 52 | Processing: 0 1 0.8 1 12 53 | Waiting: 0 1 0.8 1 12 54 | Total: 0 1 0.9 1 12 55 | 56 | Percentage of the requests served within a certain time (ms) 57 | 50% 1 58 | 66% 2 59 | 75% 2 60 | 80% 2 61 | 90% 2 62 | 95% 3 63 | 98% 4 64 | 99% 5 65 | 100% 12 (longest request) 66 | ``` 67 | #### Apache/mod_php 100 / 10 000 68 | ``` 69 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://localhost:8083/swoole_tests/swoole-performance-tests/basic/apache.php 70 | 71 | [...] 72 | 73 | Server Software: Apache/2.4.25 74 | Server Hostname: localhost 75 | Server Port: 8083 76 | 77 | Document Path: /swoole_tests/swoole-performance-tests/basic/apache.php 78 | Document Length: 2 bytes 79 | 80 | Concurrency Level: 100 81 | Time taken for tests: 5.414 seconds 82 | Complete requests: 10000 83 | Failed requests: 1 84 | (Connect: 0, Receive: 0, Length: 1, Exceptions: 0) 85 | Write errors: 0 86 | Keep-Alive requests: 9931 87 | Total transferred: 2296877 bytes 88 | HTML transferred: 19998 bytes 89 | Requests per second: 1846.98 [#/sec] (mean) 90 | Time per request: 54.143 [ms] (mean) 91 | Time per request: 0.541 [ms] (mean, across all concurrent requests) 92 | Transfer rate: 414.29 [Kbytes/sec] received 93 | 94 | Connection Times (ms) 95 | min mean[+/-sd] median max 96 | Connect: 0 0 0.6 0 8 97 | Processing: 0 15 206.5 3 5001 98 | Waiting: 0 14 200.4 2 4278 99 | Total: 0 15 206.6 3 5001 100 | 101 | Percentage of the requests served within a certain time (ms) 102 | 50% 3 103 | 66% 3 104 | 75% 4 105 | 80% 4 106 | 90% 5 107 | 95% 6 108 | 98% 10 109 | 99% 30 110 | 100% 5001 (longest request) 111 | ``` 112 | #### Apache/mod_php with 100 / 10 000 (an example run with 20 000+ per second) 113 | ``` 114 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://localhost:8083/swoole_tests/swoole-performance-tests/basic/apache.php 115 | 116 | [...] 117 | 118 | Server Software: Apache/2.4.25 119 | Server Hostname: localhost 120 | Server Port: 8083 121 | 122 | Document Path: /swoole_tests/swoole-performance-tests/basic/apache.php 123 | Document Length: 2 bytes 124 | 125 | Concurrency Level: 100 126 | Time taken for tests: 0.389 seconds 127 | Complete requests: 10000 128 | Failed requests: 0 129 | Write errors: 0 130 | Keep-Alive requests: 9946 131 | Total transferred: 2297646 bytes 132 | HTML transferred: 20000 bytes 133 | Requests per second: 25705.82 [#/sec] (mean) 134 | Time per request: 3.890 [ms] (mean) 135 | Time per request: 0.039 [ms] (mean, across all concurrent requests) 136 | Transfer rate: 5767.86 [Kbytes/sec] received 137 | 138 | Connection Times (ms) 139 | min mean[+/-sd] median max 140 | Connect: 0 0 0.6 0 8 141 | Processing: 0 4 6.8 3 202 142 | Waiting: 0 4 6.8 3 202 143 | Total: 0 4 7.0 3 208 144 | 145 | Percentage of the requests served within a certain time (ms) 146 | 50% 3 147 | 66% 4 148 | 75% 4 149 | 80% 5 150 | 90% 6 151 | 95% 8 152 | 98% 12 153 | 99% 14 154 | 100% 208 (longest request) 155 | ``` 156 | 157 | #### Swoole with 500 / 10 000 158 | ``` 159 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://localhost:8082/ 160 | 161 | [...] 162 | 163 | Server Software: swoole-http-server 164 | Server Hostname: localhost 165 | Server Port: 8082 166 | 167 | Document Path: / 168 | Document Length: 2 bytes 169 | 170 | Concurrency Level: 500 171 | Time taken for tests: 0.168 seconds 172 | Complete requests: 10000 173 | Failed requests: 0 174 | Write errors: 0 175 | Keep-Alive requests: 10000 176 | Total transferred: 1540000 bytes 177 | HTML transferred: 20000 bytes 178 | Requests per second: 59658.75 [#/sec] (mean) 179 | Time per request: 8.381 [ms] (mean) 180 | Time per request: 0.017 [ms] (mean, across all concurrent requests) 181 | Transfer rate: 8972.12 [Kbytes/sec] received 182 | 183 | Connection Times (ms) 184 | min mean[+/-sd] median max 185 | Connect: 0 1 3.6 0 22 186 | Processing: 1 7 2.6 7 23 187 | Waiting: 1 7 2.6 7 17 188 | Total: 1 8 4.8 7 32 189 | 190 | Percentage of the requests served within a certain time (ms) 191 | 50% 7 192 | 66% 7 193 | 75% 9 194 | 80% 10 195 | 90% 12 196 | 95% 18 197 | 98% 26 198 | 99% 28 199 | 100% 32 (longest request) 200 | ``` 201 | #### Apache/mod_php 500 / 10 000 202 | ``` 203 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic/apache.php 204 | 205 | [...] 206 | 207 | Server Software: Apache/2.4.25 208 | Server Hostname: 192.168.0.233 209 | Server Port: 8083 210 | 211 | Document Path: /swoole_tests/swoole-performance-tests/basic/apache.php 212 | Document Length: 2 bytes 213 | 214 | Concurrency Level: 500 215 | Time taken for tests: 5.583 seconds 216 | Complete requests: 10000 217 | Failed requests: 251 218 | (Connect: 0, Receive: 0, Length: 251, Exceptions: 0) 219 | Write errors: 0 220 | Keep-Alive requests: 9831 221 | Total transferred: 2271856 bytes 222 | HTML transferred: 19752 bytes 223 | Requests per second: 1791.00 [#/sec] (mean) 224 | Time per request: 279.174 [ms] (mean) 225 | Time per request: 0.558 [ms] (mean, across all concurrent requests) 226 | Transfer rate: 397.35 [Kbytes/sec] received 227 | 228 | Connection Times (ms) 229 | min mean[+/-sd] median max 230 | Connect: 0 1 7.7 0 57 231 | Processing: 1 139 794.9 12 5515 232 | Waiting: 1 54 474.7 12 5515 233 | Total: 1 140 797.6 12 5570 234 | 235 | Percentage of the requests served within a certain time (ms) 236 | 50% 12 237 | 66% 13 238 | 75% 14 239 | 80% 14 240 | 90% 21 241 | 95% 48 242 | 98% 4999 243 | 99% 5007 244 | 100% 5570 (longest request) 245 | ``` 246 | 247 | #### Swoole with 1 000 / 10 000 248 | ``` 249 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8082/ 250 | 251 | [...] 252 | 253 | Server Software: swoole-http-server 254 | Server Hostname: 192.168.0.233 255 | Server Port: 8082 256 | 257 | Document Path: / 258 | Document Length: 2 bytes 259 | 260 | Concurrency Level: 1000 261 | Time taken for tests: 0.286 seconds 262 | Complete requests: 10000 263 | Failed requests: 0 264 | Write errors: 0 265 | Keep-Alive requests: 10000 266 | Total transferred: 1540000 bytes 267 | HTML transferred: 20000 bytes 268 | Requests per second: 34923.27 [#/sec] (mean) 269 | Time per request: 28.634 [ms] (mean) 270 | Time per request: 0.029 [ms] (mean, across all concurrent requests) 271 | Transfer rate: 5252.13 [Kbytes/sec] received 272 | 273 | Connection Times (ms) 274 | min mean[+/-sd] median max 275 | Connect: 0 5 14.0 0 64 276 | Processing: 3 21 4.1 22 64 277 | Waiting: 0 21 4.1 22 41 278 | Total: 3 25 15.4 22 91 279 | 280 | Percentage of the requests served within a certain time (ms) 281 | 50% 22 282 | 66% 22 283 | 75% 24 284 | 80% 24 285 | 90% 46 286 | 95% 68 287 | 98% 82 288 | 99% 86 289 | 100% 91 (longest request) 290 | ``` 291 | 292 | #### Apache 1 000 / 10 000 293 | ``` 294 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic/apache.php 295 | 296 | [...] 297 | 298 | Server Software: Apache/2.4.25 299 | Server Hostname: 192.168.0.233 300 | Server Port: 8083 301 | 302 | Document Path: /swoole_tests/swoole-performance-tests/basic/apache.php 303 | Document Length: 2 bytes 304 | 305 | Concurrency Level: 1000 306 | Time taken for tests: 6.669 seconds 307 | Complete requests: 10000 308 | Failed requests: 182 309 | (Connect: 0, Receive: 0, Length: 182, Exceptions: 0) 310 | Write errors: 0 311 | Keep-Alive requests: 9818 312 | Total transferred: 2258524 bytes 313 | HTML transferred: 19636 bytes 314 | Requests per second: 1499.39 [#/sec] (mean) 315 | Time per request: 666.938 [ms] (mean) 316 | Time per request: 0.667 [ms] (mean, across all concurrent requests) 317 | Transfer rate: 330.70 [Kbytes/sec] received 318 | 319 | Connection Times (ms) 320 | min mean[+/-sd] median max 321 | Connect: 0 2 11.8 0 85 322 | Processing: 1 214 1036.4 8 6581 323 | Waiting: 1 123 806.0 8 6581 324 | Total: 1 217 1043.0 8 6661 325 | 326 | Percentage of the requests served within a certain time (ms) 327 | 50% 8 328 | 66% 9 329 | 75% 10 330 | 80% 10 331 | 90% 17 332 | 95% 73 333 | 98% 5005 334 | 99% 5521 335 | 100% 6661 (longest request) -------------------------------------------------------------------------------- /basic/apache.php: -------------------------------------------------------------------------------- 1 | set(['worker_num' => swoole_cpu_num() * 2]); 4 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 5 | $response->end('ok'); 6 | }); 7 | $http->start(); -------------------------------------------------------------------------------- /basic_class_load/README.md: -------------------------------------------------------------------------------- 1 | # Basic class load test 2 | 3 | This test has two require_once() statements. 4 | 5 | The results are: 6 | - Swoole 100 / 10 000 - Requests per second: **52451.86** 7 | - Apache/mod_php 100 / 10 000 - Requests per second: **11559.91** 8 | - Swoole 500 / 10 000 - Requests per second: **41044.00** 9 | - Apache/mod_php 500 / 10 000 - Requests per second: **1706.33** with **144 failed requests** 10 | - Swoole 1 000 / 10 000 - Requests per second: **34662.77** 11 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **1339.36** with **161 failed requests** 12 | 13 | In this test Swoole performance is unaffected comapred to the [basic test](../basic/) because Swoole loads the file only once before the HTTP server startup. 14 | On the other hand Apache/mod_php performance suffers somewhat (in fact in half in the 100 / 10 000 test) as it loads the files at every request (even with Opcache enabled there is still a cost - please see [PHP RFC: Preloading](https://wiki.php.net/rfc/preload)). 15 | 16 | #### Swoole with 100 / 10 000 17 | ``` 18 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 19 | 20 | [...] 21 | 22 | Server Software: swoole-http-server 23 | Server Hostname: 192.168.0.233 24 | Server Port: 8082 25 | 26 | Document Path: / 27 | Document Length: 2 bytes 28 | 29 | Concurrency Level: 100 30 | Time taken for tests: 0.191 seconds 31 | Complete requests: 10000 32 | Failed requests: 0 33 | Write errors: 0 34 | Keep-Alive requests: 10000 35 | Total transferred: 1540000 bytes 36 | HTML transferred: 20000 bytes 37 | Requests per second: 52451.86 [#/sec] (mean) 38 | Time per request: 1.907 [ms] (mean) 39 | Time per request: 0.019 [ms] (mean, across all concurrent requests) 40 | Transfer rate: 7888.27 [Kbytes/sec] received 41 | 42 | Connection Times (ms) 43 | min mean[+/-sd] median max 44 | Connect: 0 0 0.7 0 10 45 | Processing: 0 2 0.5 2 11 46 | Waiting: 0 2 0.5 2 5 47 | Total: 0 2 0.9 2 14 48 | 49 | Percentage of the requests served within a certain time (ms) 50 | 50% 2 51 | 66% 2 52 | 75% 2 53 | 80% 2 54 | 90% 2 55 | 95% 3 56 | 98% 4 57 | 99% 5 58 | 100% 14 (longest request) 59 | ``` 60 | 61 | #### Apache with 100 / 10 000 62 | ``` 63 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_class_load/apache.php 64 | 65 | [...] 66 | 67 | Server Software: Apache/2.4.25 68 | Server Hostname: 192.168.0.233 69 | Server Port: 8083 70 | 71 | Document Path: /swoole_tests/swoole-performance-tests/basic_class_load/apache.php 72 | Document Length: 2 bytes 73 | 74 | Concurrency Level: 100 75 | Time taken for tests: 0.865 seconds 76 | Complete requests: 10000 77 | Failed requests: 0 78 | Write errors: 0 79 | Keep-Alive requests: 9964 80 | Total transferred: 2298454 bytes 81 | HTML transferred: 20000 bytes 82 | Requests per second: 11559.91 [#/sec] (mean) 83 | Time per request: 8.651 [ms] (mean) 84 | Time per request: 0.087 [ms] (mean, across all concurrent requests) 85 | Transfer rate: 2594.72 [Kbytes/sec] received 86 | 87 | Connection Times (ms) 88 | min mean[+/-sd] median max 89 | Connect: 0 0 1.5 0 19 90 | Processing: 1 8 8.1 6 135 91 | Waiting: 1 8 8.1 6 135 92 | Total: 1 9 8.3 6 135 93 | 94 | Percentage of the requests served within a certain time (ms) 95 | 50% 6 96 | 66% 8 97 | 75% 10 98 | 80% 12 99 | 90% 18 100 | 95% 25 101 | 98% 34 102 | 99% 39 103 | 100% 135 (longest request) 104 | ``` 105 | #### Swoole 500 / 10 000 106 | ``` 107 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8082/ 108 | 109 | [...] 110 | 111 | Server Software: swoole-http-server 112 | Server Hostname: 192.168.0.233 113 | Server Port: 8082 114 | 115 | Document Path: / 116 | Document Length: 2 bytes 117 | 118 | Concurrency Level: 500 119 | Time taken for tests: 0.244 seconds 120 | Complete requests: 10000 121 | Failed requests: 0 122 | Write errors: 0 123 | Keep-Alive requests: 10000 124 | Total transferred: 1540000 bytes 125 | HTML transferred: 20000 bytes 126 | Requests per second: 41044.00 [#/sec] (mean) 127 | Time per request: 12.182 [ms] (mean) 128 | Time per request: 0.024 [ms] (mean, across all concurrent requests) 129 | Transfer rate: 6172.63 [Kbytes/sec] received 130 | 131 | Connection Times (ms) 132 | min mean[+/-sd] median max 133 | Connect: 0 1 6.1 0 42 134 | Processing: 1 10 1.8 10 42 135 | Waiting: 0 10 1.7 10 21 136 | Total: 1 11 6.5 10 54 137 | 138 | Percentage of the requests served within a certain time (ms) 139 | 50% 10 140 | 66% 11 141 | 75% 11 142 | 80% 11 143 | 90% 11 144 | 95% 20 145 | 98% 40 146 | 99% 47 147 | 100% 54 (longest request) 148 | ``` 149 | #### Apache/mod_php 500 / 10 000 150 | ``` 151 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_class_load/apache.php 152 | 153 | [...] 154 | 155 | Server Software: Apache/2.4.25 156 | Server Hostname: 192.168.0.233 157 | Server Port: 8083 158 | 159 | Document Path: /swoole_tests/swoole-performance-tests/basic_class_load/apache.php 160 | Document Length: 2 bytes 161 | 162 | Concurrency Level: 500 163 | Time taken for tests: 5.861 seconds 164 | Complete requests: 10000 165 | Failed requests: 144 166 | (Connect: 0, Receive: 0, Length: 144, Exceptions: 0) 167 | Write errors: 0 168 | Keep-Alive requests: 9853 169 | Total transferred: 2267323 bytes 170 | HTML transferred: 19714 bytes 171 | Requests per second: 1706.33 [#/sec] (mean) 172 | Time per request: 293.026 [ms] (mean) 173 | Time per request: 0.586 [ms] (mean, across all concurrent requests) 174 | Transfer rate: 377.81 [Kbytes/sec] received 175 | 176 | Connection Times (ms) 177 | min mean[+/-sd] median max 178 | Connect: 0 2 8.8 0 60 179 | Processing: 1 161 852.1 13 5791 180 | Waiting: 1 89 619.2 13 5791 181 | Total: 1 162 856.5 13 5849 182 | 183 | Percentage of the requests served within a certain time (ms) 184 | 50% 13 185 | 66% 20 186 | 75% 26 187 | 80% 31 188 | 90% 47 189 | 95% 66 190 | 98% 5004 191 | 99% 5608 192 | 100% 5849 (longest request) 193 | ``` 194 | 195 | #### Swoole 1 000 / 10 000 196 | ``` 197 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8082/ 198 | 199 | [...] 200 | 201 | Server Software: swoole-http-server 202 | Server Hostname: 192.168.0.233 203 | Server Port: 8082 204 | 205 | Document Path: / 206 | Document Length: 2 bytes 207 | 208 | Concurrency Level: 1000 209 | Time taken for tests: 0.288 seconds 210 | Complete requests: 10000 211 | Failed requests: 0 212 | Write errors: 0 213 | Keep-Alive requests: 10000 214 | Total transferred: 1540000 bytes 215 | HTML transferred: 20000 bytes 216 | Requests per second: 34662.77 [#/sec] (mean) 217 | Time per request: 28.849 [ms] (mean) 218 | Time per request: 0.029 [ms] (mean, across all concurrent requests) 219 | Transfer rate: 5212.96 [Kbytes/sec] received 220 | 221 | Connection Times (ms) 222 | min mean[+/-sd] median max 223 | Connect: 0 5 14.1 0 65 224 | Processing: 3 21 3.4 22 65 225 | Waiting: 0 21 3.4 22 41 226 | Total: 3 25 15.4 22 91 227 | 228 | Percentage of the requests served within a certain time (ms) 229 | 50% 22 230 | 66% 22 231 | 75% 22 232 | 80% 22 233 | 90% 46 234 | 95% 69 235 | 98% 82 236 | 99% 87 237 | 100% 91 (longest request) 238 | 239 | ``` 240 | #### Apache 1 000 / 10 000 241 | ``` 242 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_class_load/apache.php 243 | 244 | [...] 245 | 246 | Server Software: Apache/2.4.25 247 | Server Hostname: 192.168.0.233 248 | Server Port: 8083 249 | 250 | Document Path: /swoole_tests/swoole-performance-tests/basic_class_load/apache.php 251 | Document Length: 2 bytes 252 | 253 | Concurrency Level: 1000 254 | Time taken for tests: 7.466 seconds 255 | Complete requests: 10000 256 | Failed requests: 161 257 | (Connect: 0, Receive: 0, Length: 161, Exceptions: 0) 258 | Write errors: 0 259 | Keep-Alive requests: 9828 260 | Total transferred: 2262837 bytes 261 | HTML transferred: 19678 bytes 262 | Requests per second: 1339.36 [#/sec] (mean) 263 | Time per request: 746.622 [ms] (mean) 264 | Time per request: 0.747 [ms] (mean, across all concurrent requests) 265 | Transfer rate: 295.97 [Kbytes/sec] received 266 | 267 | Connection Times (ms) 268 | min mean[+/-sd] median max 269 | Connect: 0 2 12.6 0 87 270 | Processing: 1 230 1099.1 8 7375 271 | Waiting: 1 150 914.0 8 7375 272 | Total: 1 232 1106.8 8 7454 273 | 274 | Percentage of the requests served within a certain time (ms) 275 | 50% 8 276 | 66% 12 277 | 75% 14 278 | 80% 17 279 | 90% 45 280 | 95% 111 281 | 98% 5830 282 | 99% 5841 283 | 100% 7454 (longest request) 284 | ``` -------------------------------------------------------------------------------- /basic_class_load/apache.php: -------------------------------------------------------------------------------- 1 | set(['worker_num' => swoole_cpu_num() * 2]); 9 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 10 | $response->end('ok'); 11 | }); 12 | $http->start(); -------------------------------------------------------------------------------- /basic_class_load_multiple/README.md: -------------------------------------------------------------------------------- 1 | # Basic class load multiple test 2 | 3 | This test has two require_once() statements and loads with class_exists() 100 random classes from the Zend Framework. 4 | class_exists() triggers the autoload (in this case this is Composer's autoload). 5 | 6 | The results are: 7 | - Swoole 100 / 10 000 - Requests per second: **53625.63** 8 | - Apache/mod_php 100 / 10 000 - Requests per second: **2073.61** 9 | - Swoole 500 / 10 000 - Requests per second: **39887.20** 10 | - Apache/mod_php 500 / 10 000 - Requests per second: **1010.27** with **187 failed requests** 11 | - Swoole 1 000 / 10 000 - Requests per second: **35451.69** 12 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **1016.76** with **238 failed requests** 13 | 14 | As in the [basic_class_load test](../basic_class_load) Apache/mod_php is sufferring from the multiple autoloading. Apache shows high failure rate. 15 | 16 | #### Swoole with 100 / 10 000 17 | ``` 18 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 19 | 20 | [...] 21 | 22 | Server Software: swoole-http-server 23 | Server Hostname: 192.168.0.233 24 | Server Port: 8082 25 | 26 | Document Path: / 27 | Document Length: 2 bytes 28 | 29 | Concurrency Level: 100 30 | Time taken for tests: 0.186 seconds 31 | Complete requests: 10000 32 | Failed requests: 0 33 | Write errors: 0 34 | Keep-Alive requests: 10000 35 | Total transferred: 1540000 bytes 36 | HTML transferred: 20000 bytes 37 | Requests per second: 53625.63 [#/sec] (mean) 38 | Time per request: 1.865 [ms] (mean) 39 | Time per request: 0.019 [ms] (mean, across all concurrent requests) 40 | Transfer rate: 8064.79 [Kbytes/sec] received 41 | 42 | Connection Times (ms) 43 | min mean[+/-sd] median max 44 | Connect: 0 0 0.5 0 7 45 | Processing: 0 2 0.6 2 10 46 | Waiting: 0 2 0.6 2 10 47 | Total: 0 2 0.7 2 10 48 | 49 | Percentage of the requests served within a certain time (ms) 50 | 50% 2 51 | 66% 2 52 | 75% 2 53 | 80% 2 54 | 90% 2 55 | 95% 3 56 | 98% 4 57 | 99% 5 58 | 100% 10 (longest request) 59 | ``` 60 | 61 | #### Apache/mod_php with 100 / 10 000 62 | ``` 63 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_class_load_multiple/apache.php 64 | 65 | [...] 66 | 67 | Server Software: Apache/2.4.25 68 | Server Hostname: 192.168.0.233 69 | Server Port: 8083 70 | 71 | Document Path: /swoole_tests/swoole-performance-tests/basic_class_load_multiple/apache.php 72 | Document Length: 2 bytes 73 | 74 | Concurrency Level: 100 75 | Time taken for tests: 4.823 seconds 76 | Complete requests: 10000 77 | Failed requests: 0 78 | Write errors: 0 79 | Keep-Alive requests: 9958 80 | Total transferred: 2298159 bytes 81 | HTML transferred: 20000 bytes 82 | Requests per second: 2073.61 [#/sec] (mean) 83 | Time per request: 48.225 [ms] (mean) 84 | Time per request: 0.482 [ms] (mean, across all concurrent requests) 85 | Transfer rate: 465.38 [Kbytes/sec] received 86 | 87 | Connection Times (ms) 88 | min mean[+/-sd] median max 89 | Connect: 0 0 1.8 0 24 90 | Processing: 5 48 28.2 45 215 91 | Waiting: 4 48 28.1 45 215 92 | Total: 5 48 28.2 45 215 93 | 94 | Percentage of the requests served within a certain time (ms) 95 | 50% 45 96 | 66% 55 97 | 75% 63 98 | 80% 68 99 | 90% 85 100 | 95% 101 101 | 98% 122 102 | 99% 136 103 | 100% 215 (longest request) 104 | ``` 105 | #### Swoole 500 / 10 000 106 | ``` 107 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8082/ 108 | 109 | [...] 110 | 111 | Server Software: swoole-http-server 112 | Server Hostname: 192.168.0.233 113 | Server Port: 8082 114 | 115 | Document Path: / 116 | Document Length: 2 bytes 117 | 118 | Concurrency Level: 500 119 | Time taken for tests: 0.251 seconds 120 | Complete requests: 10000 121 | Failed requests: 0 122 | Write errors: 0 123 | Keep-Alive requests: 10000 124 | Total transferred: 1540000 bytes 125 | HTML transferred: 20000 bytes 126 | Requests per second: 39887.20 [#/sec] (mean) 127 | Time per request: 12.535 [ms] (mean) 128 | Time per request: 0.025 [ms] (mean, across all concurrent requests) 129 | Transfer rate: 5998.66 [Kbytes/sec] received 130 | 131 | Connection Times (ms) 132 | min mean[+/-sd] median max 133 | Connect: 0 1 6.3 0 43 134 | Processing: 1 10 1.9 10 43 135 | Waiting: 0 10 1.8 10 22 136 | Total: 1 11 6.8 10 56 137 | 138 | Percentage of the requests served within a certain time (ms) 139 | 50% 10 140 | 66% 11 141 | 75% 11 142 | 80% 11 143 | 90% 12 144 | 95% 22 145 | 98% 41 146 | 99% 50 147 | 100% 56 (longest request) 148 | ``` 149 | #### Apache/mod_php 500 / 10 000 150 | ``` 151 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_class_load_multiple/apache.php 152 | 153 | [...] 154 | 155 | Server Software: Apache/2.4.25 156 | Server Hostname: 192.168.0.233 157 | Server Port: 8083 158 | 159 | Document Path: /swoole_tests/swoole-performance-tests/basic_class_load_multiple/apache.php 160 | Document Length: 2 bytes 161 | 162 | Concurrency Level: 500 163 | Time taken for tests: 9.898 seconds 164 | Complete requests: 10000 165 | Failed requests: 187 166 | (Connect: 0, Receive: 0, Length: 187, Exceptions: 0) 167 | Write errors: 0 168 | Keep-Alive requests: 9808 169 | Total transferred: 2257076 bytes 170 | HTML transferred: 19626 bytes 171 | Requests per second: 1010.27 [#/sec] (mean) 172 | Time per request: 494.916 [ms] (mean) 173 | Time per request: 0.990 [ms] (mean, across all concurrent requests) 174 | Transfer rate: 222.68 [Kbytes/sec] received 175 | 176 | Connection Times (ms) 177 | min mean[+/-sd] median max 178 | Connect: 0 1 7.4 0 57 179 | Processing: 4 278 1095.7 78 9824 180 | Waiting: 4 187 881.5 77 9824 181 | Total: 4 280 1099.9 78 9881 182 | 183 | Percentage of the requests served within a certain time (ms) 184 | 50% 78 185 | 66% 99 186 | 75% 114 187 | 80% 124 188 | 90% 161 189 | 95% 221 190 | 98% 5006 191 | 99% 5229 192 | 100% 9881 (longest request) 193 | ``` 194 | #### Swoole 1 000 / 10 000 195 | ``` 196 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8082/ 197 | 198 | [...] 199 | 200 | Server Software: swoole-http-server 201 | Server Hostname: 192.168.0.233 202 | Server Port: 8082 203 | 204 | Document Path: / 205 | Document Length: 2 bytes 206 | 207 | Concurrency Level: 1000 208 | Time taken for tests: 0.282 seconds 209 | Complete requests: 10000 210 | Failed requests: 0 211 | Write errors: 0 212 | Keep-Alive requests: 10000 213 | Total transferred: 1540000 bytes 214 | HTML transferred: 20000 bytes 215 | Requests per second: 35451.69 [#/sec] (mean) 216 | Time per request: 28.207 [ms] (mean) 217 | Time per request: 0.028 [ms] (mean, across all concurrent requests) 218 | Transfer rate: 5331.60 [Kbytes/sec] received 219 | 220 | Connection Times (ms) 221 | min mean[+/-sd] median max 222 | Connect: 0 5 14.8 0 72 223 | Processing: 2 20 3.6 21 72 224 | Waiting: 0 20 3.5 21 35 225 | Total: 2 24 14.8 21 94 226 | 227 | Percentage of the requests served within a certain time (ms) 228 | 50% 21 229 | 66% 21 230 | 75% 22 231 | 80% 22 232 | 90% 36 233 | 95% 65 234 | 98% 82 235 | 99% 88 236 | 100% 94 (longest request) 237 | ``` 238 | #### Apache/mod_php 1 000 / 10 000 239 | ``` 240 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_class_load_multiple/apache.php 241 | 242 | [...] 243 | 244 | Server Software: Apache/2.4.25 245 | Server Hostname: 192.168.0.233 246 | Server Port: 8083 247 | 248 | Document Path: /swoole_tests/swoole-performance-tests/basic_class_load_multiple/apache.php 249 | Document Length: 2 bytes 250 | 251 | Concurrency Level: 1000 252 | Time taken for tests: 9.835 seconds 253 | Complete requests: 10000 254 | Failed requests: 238 255 | (Connect: 0, Receive: 0, Length: 238, Exceptions: 0) 256 | Write errors: 0 257 | Keep-Alive requests: 9762 258 | Total transferred: 2245556 bytes 259 | HTML transferred: 19524 bytes 260 | Requests per second: 1016.76 [#/sec] (mean) 261 | Time per request: 983.514 [ms] (mean) 262 | Time per request: 0.984 [ms] (mean, across all concurrent requests) 263 | Transfer rate: 222.97 [Kbytes/sec] received 264 | 265 | Connection Times (ms) 266 | min mean[+/-sd] median max 267 | Connect: 0 2 11.8 0 82 268 | Processing: 5 278 956.4 119 9713 269 | Waiting: 4 161 607.0 117 9713 270 | Total: 5 280 958.6 120 9777 271 | 272 | Percentage of the requests served within a certain time (ms) 273 | 50% 120 274 | 66% 147 275 | 75% 165 276 | 80% 177 277 | 90% 215 278 | 95% 262 279 | 98% 5006 280 | 99% 5016 281 | 100% 9777 (longest request) 282 | ``` -------------------------------------------------------------------------------- /basic_class_load_multiple/apache.php: -------------------------------------------------------------------------------- 1 | set(['worker_num' => swoole_cpu_num() * 2]); 11 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 12 | $response->end('ok'); 13 | }); 14 | $http->start(); -------------------------------------------------------------------------------- /basic_query/README.md: -------------------------------------------------------------------------------- 1 | # Basic query test 2 | 3 | The test does a single query to the database and prints the result. No connection pooling or caching is used. 4 | 5 | The results are: 6 | - Swoole 100 / 10 000 - Requests per second: **1804.08** 7 | - Apache/mod_php 100 / 10 000 - Requests per second: **1314.86** 8 | - Swoole 5000 / 10 000 - Not performed (due to number of DB connection) 9 | - Apache/mod_php 5000 / 10 000 - Not performed (due to number of DB connections) 10 | - Swoole 1 000 / 10 000 - Not performed (due to number of DB connection) 11 | - Apache/mod_php 1 000 / 10 000 - Not performed (due to number of DB connections) 12 | 13 | In this test Swoole has some advantage because the coroutine aware MySQL client is used. Both will perform much better if connection pooling is used. 14 | As both server will open a number of database connections equal to the number of incoming requests and this will overload the database no tests with 1 000 / 10 000 are performed. 15 | 16 | ##### Swoole 100 / 10 000 17 | ``` 18 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 19 | 20 | [...] 21 | 22 | Server Software: swoole-http-server 23 | Server Hostname: 192.168.0.233 24 | Server Port: 8082 25 | 26 | Document Path: / 27 | Document Length: 792 bytes 28 | 29 | Concurrency Level: 100 30 | Time taken for tests: 5.543 seconds 31 | Complete requests: 10000 32 | Failed requests: 0 33 | Write errors: 0 34 | Keep-Alive requests: 10000 35 | Total transferred: 9460000 bytes 36 | HTML transferred: 7920000 bytes 37 | Requests per second: 1804.08 [#/sec] (mean) 38 | Time per request: 55.430 [ms] (mean) 39 | Time per request: 0.554 [ms] (mean, across all concurrent requests) 40 | Transfer rate: 1666.66 [Kbytes/sec] received 41 | 42 | Connection Times (ms) 43 | min mean[+/-sd] median max 44 | Connect: 0 0 0.9 0 12 45 | Processing: 10 55 136.6 25 907 46 | Waiting: 3 55 136.6 25 907 47 | Total: 10 55 136.9 25 916 48 | 49 | Percentage of the requests served within a certain time (ms) 50 | 50% 25 51 | 66% 26 52 | 75% 28 53 | 80% 30 54 | 90% 37 55 | 95% 57 56 | 98% 666 57 | 99% 677 58 | 100% 916 (longest request) 59 | ``` 60 | #### Apache 100 / 10 000 61 | ``` 62 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_query/apache.php 63 | 64 | [...] 65 | 66 | 67 | Server Software: Apache/2.4.25 68 | Server Hostname: 192.168.0.233 69 | Server Port: 8083 70 | 71 | Document Path: /swoole_tests/swoole-performance-tests/basic_query/apache.php 72 | Document Length: 792 bytes 73 | 74 | Concurrency Level: 100 75 | Time taken for tests: 7.605 seconds 76 | Complete requests: 10000 77 | Failed requests: 0 78 | Write errors: 0 79 | Keep-Alive requests: 9933 80 | Total transferred: 10447109 bytes 81 | HTML transferred: 7920000 bytes 82 | Requests per second: 1314.86 [#/sec] (mean) 83 | Time per request: 76.054 [ms] (mean) 84 | Time per request: 0.761 [ms] (mean, across all concurrent requests) 85 | Transfer rate: 1341.45 [Kbytes/sec] received 86 | 87 | Connection Times (ms) 88 | min mean[+/-sd] median max 89 | Connect: 0 0 1.0 0 12 90 | Processing: 2 67 424.0 8 5556 91 | Waiting: 2 67 424.0 8 5556 92 | Total: 2 67 424.6 8 5562 93 | 94 | Percentage of the requests served within a certain time (ms) 95 | 50% 8 96 | 66% 13 97 | 75% 15 98 | 80% 17 99 | 90% 21 100 | 95% 25 101 | 98% 1005 102 | 99% 2526 103 | 100% 5562 (longest request) 104 | ``` -------------------------------------------------------------------------------- /basic_query/apache.php: -------------------------------------------------------------------------------- 1 | connect_error) 9 | { 10 | die("$mysqli->connect_errno: $mysqli->connect_error"); 11 | } 12 | 13 | $stmt = $mysqli->prepare("SELECT * FROM test1"); 14 | $stmt->execute(); 15 | $result = $stmt->get_result(); 16 | $data = []; 17 | while($row = $result->fetch_assoc()) { 18 | $data[] = $row; 19 | } 20 | print_r($data); 21 | 22 | 23 | -------------------------------------------------------------------------------- /basic_query/swoole.php: -------------------------------------------------------------------------------- 1 | set(['worker_num' => swoole_cpu_num() * 2]); 8 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 9 | 10 | $swoole_mysql = new Swoole\Coroutine\MySQL(); 11 | $swoole_mysql->connect([ 12 | 'host' => MYSQL_HOST, 13 | 'port' => MYSQL_PORT, 14 | 'user' => MYSQL_USER, 15 | 'password' => MYSQL_PASS, 16 | 'database' => MYSQL_DB, 17 | ]); 18 | //$res = $swoole_mysql->query('select sleep(1)'); 19 | $stmt = $swoole_mysql->prepare("SELECT * FROM test1"); 20 | if ($stmt === FALSE) { 21 | print $swoole_mysql->connect_error; 22 | print $swoole_mysql->error; 23 | } 24 | $data = $stmt->execute(); 25 | //$data = $stmt->fetchAll(); 26 | 27 | $str = print_r($data, TRUE); 28 | 29 | $response->end($str); 30 | }); 31 | $http->start(); -------------------------------------------------------------------------------- /basic_query_with_pool/README.md: -------------------------------------------------------------------------------- 1 | # Basic query with pool test 2 | 3 | Swoole uses Pool implementation based on Swoole\Channel and Apache/mod_php uses MySQLi persistent connections. 4 | 5 | The results are: 6 | - Swoole 100 / 10 000 - Requests per second: **4163.17** 7 | - Apache/mod_php 100 / 10 000 - Requests per second: **2327.34** 8 | - Swoole 500 / 10 000 - Requests per second: **4279.57** 9 | - Apache/mod_php 500 / 10 000 - Requests per second: **1059.98** with **228 failed requests** 10 | - Swoole 1 000 / 10 000 - Requests per second: **4326.38** 11 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **failed, 9547 requests completed** 12 | 13 | Both show much better performance than the non-pooled test. 14 | It is important to note that the persistent connections in MySQLi do perform [additional connection cleanup](https://www.php.net/manual/en/mysqli.persistconns.php) when the connection is returned back to the pool. 15 | In Swoole this is left to the developer to ensure the connection that is returned to the pool is in clean state. 16 | So Apache/mod_php to match Swoole behaviour it needs to be compiled with MYSQLI_NO_CHANGE_USER_ON_PCONNECT defined. 17 | This test is performed on a standard PHP config where this is not set. 18 | 19 | #### Swoole 100 / 10 000 20 | ``` 21 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 22 | 23 | [...] 24 | 25 | Server Software: swoole-http-server 26 | Server Hostname: 192.168.0.233 27 | Server Port: 8082 28 | 29 | Document Path: / 30 | Document Length: 792 bytes 31 | 32 | Concurrency Level: 100 33 | Time taken for tests: 2.402 seconds 34 | Complete requests: 10000 35 | Failed requests: 0 36 | Write errors: 0 37 | Keep-Alive requests: 10000 38 | Total transferred: 9460000 bytes 39 | HTML transferred: 7920000 bytes 40 | Requests per second: 4163.17 [#/sec] (mean) 41 | Time per request: 24.020 [ms] (mean) 42 | Time per request: 0.240 [ms] (mean, across all concurrent requests) 43 | Transfer rate: 3846.06 [Kbytes/sec] received 44 | 45 | Connection Times (ms) 46 | min mean[+/-sd] median max 47 | Connect: 0 0 0.8 0 11 48 | Processing: 1 24 6.6 23 104 49 | Waiting: 1 24 6.6 23 104 50 | Total: 1 24 6.7 23 108 51 | 52 | Percentage of the requests served within a certain time (ms) 53 | 50% 23 54 | 66% 26 55 | 75% 27 56 | 80% 28 57 | 90% 31 58 | 95% 33 59 | 98% 45 60 | 99% 50 61 | 100% 108 (longest request) 62 | ``` 63 | #### Apache 100 / 10 000 64 | ``` 65 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_query_with_pool/apache.php 66 | This is ApacheBench, Version 2.3 <$Revision: 1430300 $> 67 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 68 | Licensed to The Apache Software Foundation, http://www.apache.org/ 69 | 70 | Benchmarking 192.168.0.233 (be patient) 71 | Completed 1000 requests 72 | Completed 2000 requests 73 | Completed 3000 requests 74 | Completed 4000 requests 75 | Completed 5000 requests 76 | Completed 6000 requests 77 | Completed 7000 requests 78 | Completed 8000 requests 79 | Completed 9000 requests 80 | Completed 10000 requests 81 | Finished 10000 requests 82 | 83 | 84 | Server Software: Apache/2.4.25 85 | Server Hostname: 192.168.0.233 86 | Server Port: 8083 87 | 88 | Document Path: /swoole_tests/swoole-performance-tests/basic_query_with_pool/apache.php 89 | Document Length: 792 bytes 90 | 91 | Concurrency Level: 100 92 | Time taken for tests: 4.297 seconds 93 | Complete requests: 10000 94 | Failed requests: 0 95 | Write errors: 0 96 | Keep-Alive requests: 9958 97 | Total transferred: 10447772 bytes 98 | HTML transferred: 7920000 bytes 99 | Requests per second: 2327.34 [#/sec] (mean) 100 | Time per request: 42.968 [ms] (mean) 101 | Time per request: 0.430 [ms] (mean, across all concurrent requests) 102 | Transfer rate: 2374.56 [Kbytes/sec] received 103 | 104 | Connection Times (ms) 105 | min mean[+/-sd] median max 106 | Connect: 0 0 1.0 0 10 107 | Processing: 2 43 30.6 40 2326 108 | Waiting: 2 43 30.6 40 2326 109 | Total: 2 43 30.8 40 2335 110 | 111 | Percentage of the requests served within a certain time (ms) 112 | 50% 40 113 | 66% 42 114 | 75% 44 115 | 80% 46 116 | 90% 57 117 | 95% 62 118 | 98% 67 119 | 99% 70 120 | 100% 2335 (longest request) 121 | ``` 122 | #### Swoole 500 / 10 000 123 | ``` 124 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 125 | 126 | [...] 127 | 128 | Server Software: swoole-http-server 129 | Server Hostname: 192.168.0.233 130 | Server Port: 8082 131 | 132 | Document Path: / 133 | Document Length: 792 bytes 134 | 135 | Concurrency Level: 100 136 | Time taken for tests: 2.337 seconds 137 | Complete requests: 10000 138 | Failed requests: 0 139 | Write errors: 0 140 | Keep-Alive requests: 10000 141 | Total transferred: 9460000 bytes 142 | HTML transferred: 7920000 bytes 143 | Requests per second: 4279.57 [#/sec] (mean) 144 | Time per request: 23.367 [ms] (mean) 145 | Time per request: 0.234 [ms] (mean, across all concurrent requests) 146 | Transfer rate: 3953.58 [Kbytes/sec] received 147 | 148 | Connection Times (ms) 149 | min mean[+/-sd] median max 150 | Connect: 0 0 0.8 0 11 151 | Processing: 1 23 6.8 23 102 152 | Waiting: 1 23 6.8 23 102 153 | Total: 1 23 7.0 23 107 154 | 155 | Percentage of the requests served within a certain time (ms) 156 | 50% 23 157 | 66% 25 158 | 75% 27 159 | 80% 28 160 | 90% 30 161 | 95% 32 162 | 98% 44 163 | 99% 50 164 | 100% 107 (longest request) 165 | ``` 166 | #### Apache/mod_php 500 / 10 000 167 | ``` 168 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_query_with_pool/apache.php 169 | 170 | [...] 171 | 172 | Server Software: Apache/2.4.25 173 | Server Hostname: 192.168.0.233 174 | Server Port: 8083 175 | 176 | Document Path: /swoole_tests/swoole-performance-tests/basic_query_with_pool/apache.php 177 | Document Length: 792 bytes 178 | 179 | Concurrency Level: 500 180 | Time taken for tests: 9.434 seconds 181 | Complete requests: 10000 182 | Failed requests: 228 183 | (Connect: 0, Receive: 0, Length: 228, Exceptions: 0) 184 | Write errors: 0 185 | Keep-Alive requests: 9772 186 | Total transferred: 10212012 bytes 187 | HTML transferred: 7739424 bytes 188 | Requests per second: 1059.98 [#/sec] (mean) 189 | Time per request: 471.709 [ms] (mean) 190 | Time per request: 0.943 [ms] (mean, across all concurrent requests) 191 | Transfer rate: 1057.08 [Kbytes/sec] received 192 | 193 | Connection Times (ms) 194 | min mean[+/-sd] median max 195 | Connect: 0 1 6.2 0 56 196 | Processing: 2 241 854.2 95 9372 197 | Waiting: 2 128 447.3 93 9372 198 | Total: 2 242 855.6 95 9428 199 | 200 | Percentage of the requests served within a certain time (ms) 201 | 50% 95 202 | 66% 106 203 | 75% 111 204 | 80% 116 205 | 90% 135 206 | 95% 160 207 | 98% 5004 208 | 99% 5005 209 | 100% 9428 (longest request) 210 | ``` 211 | #### Swoole 1 000 / 10 000 212 | ``` 213 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8082/ 214 | 215 | [...] 216 | 217 | Server Software: swoole-http-server 218 | Server Hostname: 192.168.0.233 219 | Server Port: 8082 220 | 221 | Document Path: / 222 | Document Length: 792 bytes 223 | 224 | Concurrency Level: 1000 225 | Time taken for tests: 2.311 seconds 226 | Complete requests: 10000 227 | Failed requests: 0 228 | Write errors: 0 229 | Keep-Alive requests: 10000 230 | Total transferred: 9460000 bytes 231 | HTML transferred: 7920000 bytes 232 | Requests per second: 4326.38 [#/sec] (mean) 233 | Time per request: 231.140 [ms] (mean) 234 | Time per request: 0.231 [ms] (mean, across all concurrent requests) 235 | Transfer rate: 3996.83 [Kbytes/sec] received 236 | 237 | Connection Times (ms) 238 | min mean[+/-sd] median max 239 | Connect: 0 6 20.1 0 101 240 | Processing: 29 210 36.5 209 346 241 | Waiting: 2 210 36.6 209 346 242 | Total: 32 216 32.2 210 355 243 | 244 | Percentage of the requests served within a certain time (ms) 245 | 50% 210 246 | 66% 216 247 | 75% 221 248 | 80% 229 249 | 90% 254 250 | 95% 295 251 | 98% 317 252 | 99% 325 253 | 100% 355 (longest request) 254 | ``` 255 | #### Apache/mod_php 1 000 / 10 000 256 | ``` 257 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_query_with_pool/apache.php 258 | This is ApacheBench, Version 2.3 <$Revision: 1430300 $> 259 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 260 | Licensed to The Apache Software Foundation, http://www.apache.org/ 261 | 262 | Benchmarking 192.168.0.233 (be patient) 263 | Completed 1000 requests 264 | Completed 2000 requests 265 | Completed 3000 requests 266 | Completed 4000 requests 267 | Completed 5000 requests 268 | Completed 6000 requests 269 | Completed 7000 requests 270 | Completed 8000 requests 271 | Completed 9000 requests 272 | apr_socket_recv: Connection reset by peer (104) 273 | Total of 9547 requests completed 274 | ``` 275 | -------------------------------------------------------------------------------- /basic_query_with_pool/apache.php: -------------------------------------------------------------------------------- 1 | connect_error) 11 | { 12 | die("$mysqli->connect_errno: $mysqli->connect_error"); 13 | } 14 | 15 | $stmt = $mysqli->prepare("SELECT * FROM test1"); 16 | $stmt->execute(); 17 | $result = $stmt->get_result(); 18 | $data = []; 19 | while($row = $result->fetch_assoc()) { 20 | $data[] = $row; 21 | } 22 | print_r($data); 23 | 24 | 25 | -------------------------------------------------------------------------------- /basic_query_with_pool/swoole.php: -------------------------------------------------------------------------------- 1 | available_connections)) { 16 | $this->initialize_connections($connection_class); 17 | } 18 | 19 | $Connection = $this->available_connections[$connection_class]->pop();//blocks and waits until one is available if there are no available ones 20 | 21 | return $Connection; 22 | } 23 | 24 | public function free_connection(ConnectionInterface $Connection) : void 25 | { 26 | $connection_class = get_class($Connection); 27 | 28 | $this->available_connections[$connection_class]->push($Connection); 29 | } 30 | 31 | private function initialize_connections(string $connection_class) : void 32 | { 33 | $this->available_connections[$connection_class] = new \Swoole\Coroutine\Channel(self::MAX_CONNECTIONS); 34 | for ($aa = 0; $aa < self::MAX_CONNECTIONS ; $aa++) { 35 | $Connection = new $connection_class(); 36 | $this->available_connections[$connection_class]->push($Connection); 37 | } 38 | } 39 | 40 | } 41 | 42 | interface ConnectionInterface 43 | { 44 | } 45 | 46 | class MysqlConnection implements ConnectionInterface 47 | { 48 | 49 | private const CONNECTION_SETTINGS = [ 50 | 'host' => MYSQL_HOST, 51 | 'port' => MYSQL_PORT, 52 | 'user' => MYSQL_USER, 53 | 'password' => MYSQL_PASS, 54 | 'database' => MYSQL_DB, 55 | ]; 56 | 57 | private $SwooleMysql; 58 | 59 | public function __construct() 60 | { 61 | $this->SwooleMysql = new Swoole\Coroutine\MySQL(); 62 | $this->SwooleMysql->connect(self::CONNECTION_SETTINGS); 63 | } 64 | 65 | public function __call(string $method, array $args) 66 | { 67 | return call_user_func_array([$this->SwooleMysql, $method], $args); 68 | } 69 | 70 | public function __get(string $property) 71 | { 72 | return $this->SwooleMysql->{$property}; 73 | } 74 | 75 | } 76 | 77 | 78 | $http = new Swoole\Http\Server('0.0.0.0', 8082, SWOOLE_PROCESS); 79 | $http->set(['worker_num' => swoole_cpu_num() * 2]); 80 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 81 | 82 | static $Pool; 83 | if ($Pool === NULL) { 84 | $Pool = new Pool; 85 | } 86 | 87 | $Connection = $Pool->get_connection(MysqlConnection::class); 88 | 89 | $stmt = $Connection->prepare("SELECT * FROM test1"); 90 | if ($stmt === FALSE) { 91 | print $Connection->connect_error; 92 | print $Connection->error; 93 | } 94 | $data = $stmt->execute(); 95 | $Pool->free_connection($Connection); 96 | 97 | $str = print_r($data, TRUE); 98 | 99 | $response->end($str); 100 | }); 101 | $http->start(); -------------------------------------------------------------------------------- /basic_query_with_pool_and_caching/README.md: -------------------------------------------------------------------------------- 1 | # Basic query with pool and caching test 2 | 3 | This test performs a query and then a cache read. 4 | In Swoole this is a memory read (as swoole is persistent) and in Apache/mod_php this is implemented with APCu. 5 | This load basically compares the unserialization speed and APCu read spead versus memory access. 6 | 7 | The results are: 8 | - Swoole 100 / 10 000 - Requests per second: **53499.11** 9 | - Apache/mod_php 100 / 10 000 - Requests per second: **25141.67** (note: many tests are in the range of 1900-2000) 10 | - Swoole 100 / 10 000 - Requests per second: **41790.99** 11 | - Apache/mod_php 100 / 10 000 - Requests per second: **1831.16** with **237 failed requests** 12 | - Swoole 1 000 / 10 000 - Requests per second: **38591.86** 13 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **1535.84** with **107 failed requests** 14 | 15 | #### Swoole 100 / 10 000 16 | ``` 17 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 18 | 19 | [...] 20 | 21 | Server Software: swoole-http-server 22 | Server Hostname: 192.168.0.233 23 | Server Port: 8082 24 | 25 | Document Path: / 26 | Document Length: 792 bytes 27 | 28 | Concurrency Level: 100 29 | Time taken for tests: 0.187 seconds 30 | Complete requests: 10000 31 | Failed requests: 0 32 | Write errors: 0 33 | Keep-Alive requests: 10000 34 | Total transferred: 9460000 bytes 35 | HTML transferred: 7920000 bytes 36 | Requests per second: 53499.11 [#/sec] (mean) 37 | Time per request: 1.869 [ms] (mean) 38 | Time per request: 0.019 [ms] (mean, across all concurrent requests) 39 | Transfer rate: 49423.98 [Kbytes/sec] received 40 | 41 | Connection Times (ms) 42 | min mean[+/-sd] median max 43 | Connect: 0 0 0.4 0 6 44 | Processing: 0 2 0.4 2 7 45 | Waiting: 0 2 0.4 2 4 46 | Total: 0 2 0.6 2 9 47 | 48 | Percentage of the requests served within a certain time (ms) 49 | 50% 2 50 | 66% 2 51 | 75% 2 52 | 80% 2 53 | 90% 2 54 | 95% 3 55 | 98% 4 56 | 99% 5 57 | 100% 9 (longest request) 58 | ``` 59 | #### Apache 100 / 10 000 60 | ``` 61 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests/basic_query_with_pool_and_caching (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_query_with_pool_and_caching/apache.php 62 | 63 | [...] 64 | 65 | Server Software: Apache/2.4.25 66 | Server Hostname: 192.168.0.233 67 | Server Port: 8083 68 | 69 | Document Path: /swoole_tests/swoole-performance-tests/basic_query_with_pool_and_caching/apache.php 70 | Document Length: 792 bytes 71 | 72 | Concurrency Level: 100 73 | Time taken for tests: 0.398 seconds 74 | Complete requests: 10000 75 | Failed requests: 0 76 | Write errors: 0 77 | Keep-Alive requests: 9931 78 | Total transferred: 10446982 bytes 79 | HTML transferred: 7920000 bytes 80 | Requests per second: 25141.67 [#/sec] (mean) 81 | Time per request: 3.977 [ms] (mean) 82 | Time per request: 0.040 [ms] (mean, across all concurrent requests) 83 | Transfer rate: 25649.86 [Kbytes/sec] received 84 | 85 | Connection Times (ms) 86 | min mean[+/-sd] median max 87 | Connect: 0 0 0.8 0 8 88 | Processing: 0 4 5.6 3 310 89 | Waiting: 0 4 5.6 3 310 90 | Total: 0 4 5.8 3 318 91 | 92 | Percentage of the requests served within a certain time (ms) 93 | 50% 3 94 | 66% 4 95 | 75% 4 96 | 80% 5 97 | 90% 6 98 | 95% 8 99 | 98% 11 100 | 99% 14 101 | 100% 318 (longest request) 102 | ``` 103 | #### Swoole 500 / 10 000 104 | ``` 105 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8082/ 106 | 107 | [...] 108 | 109 | Server Software: swoole-http-server 110 | Server Hostname: 192.168.0.233 111 | Server Port: 8082 112 | 113 | Document Path: / 114 | Document Length: 792 bytes 115 | 116 | Concurrency Level: 500 117 | Time taken for tests: 0.239 seconds 118 | Complete requests: 10000 119 | Failed requests: 0 120 | Write errors: 0 121 | Keep-Alive requests: 10000 122 | Total transferred: 9460000 bytes 123 | HTML transferred: 7920000 bytes 124 | Requests per second: 41790.99 [#/sec] (mean) 125 | Time per request: 11.964 [ms] (mean) 126 | Time per request: 0.024 [ms] (mean, across all concurrent requests) 127 | Transfer rate: 38607.70 [Kbytes/sec] received 128 | 129 | Connection Times (ms) 130 | min mean[+/-sd] median max 131 | Connect: 0 2 7.3 0 47 132 | Processing: 1 9 2.4 10 48 133 | Waiting: 0 9 2.4 10 23 134 | Total: 1 11 8.8 10 65 135 | 136 | Percentage of the requests served within a certain time (ms) 137 | 50% 10 138 | 66% 10 139 | 75% 11 140 | 80% 11 141 | 90% 11 142 | 95% 29 143 | 98% 50 144 | 99% 58 145 | 100% 65 (longest request) 146 | ``` 147 | #### Apache 500 / 10 000 148 | ``` 149 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_query_with_pool_and_caching/apache.php 150 | 151 | [...] 152 | 153 | Server Software: Apache/2.4.25 154 | Server Hostname: 192.168.0.233 155 | Server Port: 8083 156 | 157 | Document Path: /swoole_tests/swoole-performance-tests/basic_query_with_pool_and_caching/apache.php 158 | Document Length: 792 bytes 159 | 160 | Concurrency Level: 500 161 | Time taken for tests: 5.461 seconds 162 | Complete requests: 10000 163 | Failed requests: 237 164 | (Connect: 0, Receive: 0, Length: 237, Exceptions: 0) 165 | Write errors: 0 166 | Keep-Alive requests: 9835 167 | Total transferred: 10315566 bytes 168 | HTML transferred: 7817832 bytes 169 | Requests per second: 1831.16 [#/sec] (mean) 170 | Time per request: 273.052 [ms] (mean) 171 | Time per request: 0.546 [ms] (mean, across all concurrent requests) 172 | Transfer rate: 1844.67 [Kbytes/sec] received 173 | 174 | Connection Times (ms) 175 | min mean[+/-sd] median max 176 | Connect: 0 1 7.9 0 59 177 | Processing: 1 136 792.8 8 5391 178 | Waiting: 1 54 481.0 8 5391 179 | Total: 1 138 795.9 8 5448 180 | 181 | Percentage of the requests served within a certain time (ms) 182 | 50% 8 183 | 66% 9 184 | 75% 10 185 | 80% 13 186 | 90% 18 187 | 95% 42 188 | 98% 4999 189 | 99% 5006 190 | 100% 5448 (longest request) 191 | ``` 192 | 193 | #### Swoole 1 000 / 10 000 194 | ``` 195 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8082/ 196 | 197 | [...] 198 | 199 | Server Software: swoole-http-server 200 | Server Hostname: 192.168.0.233 201 | Server Port: 8082 202 | 203 | Document Path: / 204 | Document Length: 792 bytes 205 | 206 | Concurrency Level: 1000 207 | Time taken for tests: 0.259 seconds 208 | Complete requests: 10000 209 | Failed requests: 0 210 | Write errors: 0 211 | Keep-Alive requests: 10000 212 | Total transferred: 9460000 bytes 213 | HTML transferred: 7920000 bytes 214 | Requests per second: 38591.86 [#/sec] (mean) 215 | Time per request: 25.912 [ms] (mean) 216 | Time per request: 0.026 [ms] (mean, across all concurrent requests) 217 | Transfer rate: 35652.25 [Kbytes/sec] received 218 | 219 | Connection Times (ms) 220 | min mean[+/-sd] median max 221 | Connect: 0 4 13.2 0 62 222 | Processing: 2 18 4.5 18 63 223 | Waiting: 0 18 4.5 18 32 224 | Total: 2 23 14.2 18 84 225 | 226 | Percentage of the requests served within a certain time (ms) 227 | 50% 18 228 | 66% 19 229 | 75% 23 230 | 80% 25 231 | 90% 38 232 | 95% 61 233 | 98% 75 234 | 99% 80 235 | 100% 84 (longest request) 236 | ``` 237 | #### Apache 1000 / 10 000 238 | ``` 239 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/basic_query_with_pool_and_caching/apache.php 240 | 241 | [...] 242 | 243 | Server Software: Apache/2.4.25 244 | Server Hostname: 192.168.0.233 245 | Server Port: 8083 246 | 247 | Document Path: /swoole_tests/swoole-performance-tests/basic_query_with_pool_and_caching/apache.php 248 | Document Length: 792 bytes 249 | 250 | Concurrency Level: 1000 251 | Time taken for tests: 6.511 seconds 252 | Complete requests: 10000 253 | Failed requests: 107 254 | (Connect: 0, Receive: 0, Length: 107, Exceptions: 0) 255 | Write errors: 0 256 | Keep-Alive requests: 9865 257 | Total transferred: 10337110 bytes 258 | HTML transferred: 7835256 bytes 259 | Requests per second: 1535.84 [#/sec] (mean) 260 | Time per request: 651.110 [ms] (mean) 261 | Time per request: 0.651 [ms] (mean, across all concurrent requests) 262 | Transfer rate: 1550.40 [Kbytes/sec] received 263 | 264 | Connection Times (ms) 265 | min mean[+/-sd] median max 266 | Connect: 0 2 11.4 0 82 267 | Processing: 1 162 881.0 4 6425 268 | Waiting: 1 109 723.1 4 6425 269 | Total: 1 164 888.2 4 6499 270 | 271 | Percentage of the requests served within a certain time (ms) 272 | 50% 4 273 | 66% 5 274 | 75% 6 275 | 80% 6 276 | 90% 9 277 | 95% 16 278 | 98% 4999 279 | 99% 5005 280 | 100% 6499 (longest request) 281 | ``` -------------------------------------------------------------------------------- /basic_query_with_pool_and_caching/apache.php: -------------------------------------------------------------------------------- 1 | connect_error) 14 | { 15 | die("$mysqli->connect_errno: $mysqli->connect_error"); 16 | } 17 | 18 | $stmt = $mysqli->prepare("SELECT * FROM test1"); 19 | $stmt->execute(); 20 | $result = $stmt->get_result(); 21 | $data = []; 22 | while($row = $result->fetch_assoc()) { 23 | $data[] = $row; 24 | } 25 | 26 | apcu_add('test1_data', $data); 27 | } 28 | 29 | print_r($data); 30 | 31 | 32 | -------------------------------------------------------------------------------- /basic_query_with_pool_and_caching/swoole.php: -------------------------------------------------------------------------------- 1 | available_connections)) { 16 | $this->initialize_connections($connection_class); 17 | } 18 | 19 | $Connection = $this->available_connections[$connection_class]->pop();//blocks and waits until one is available if there are no available ones 20 | 21 | return $Connection; 22 | } 23 | 24 | public function free_connection(ConnectionInterface $Connection) : void 25 | { 26 | $connection_class = get_class($Connection); 27 | 28 | $this->available_connections[$connection_class]->push($Connection); 29 | } 30 | 31 | private function initialize_connections(string $connection_class) : void 32 | { 33 | $this->available_connections[$connection_class] = new \Swoole\Coroutine\Channel(self::MAX_CONNECTIONS); 34 | for ($aa = 0; $aa < self::MAX_CONNECTIONS ; $aa++) { 35 | $Connection = new $connection_class(); 36 | $this->available_connections[$connection_class]->push($Connection); 37 | } 38 | } 39 | 40 | } 41 | 42 | interface ConnectionInterface 43 | { 44 | } 45 | 46 | class MysqlConnection implements ConnectionInterface 47 | { 48 | 49 | private const CONNECTION_SETTINGS = [ 50 | 'host' => MYSQL_HOST, 51 | 'port' => MYSQL_PORT, 52 | 'user' => MYSQL_USER, 53 | 'password' => MYSQL_PASS, 54 | 'database' => MYSQL_DB, 55 | ]; 56 | 57 | private $SwooleMysql; 58 | 59 | public function __construct() 60 | { 61 | $this->SwooleMysql = new Swoole\Coroutine\MySQL(); 62 | $this->SwooleMysql->connect(self::CONNECTION_SETTINGS); 63 | } 64 | 65 | public function __call(string $method, array $args) 66 | { 67 | return call_user_func_array([$this->SwooleMysql, $method], $args); 68 | } 69 | 70 | public function __get(string $property) 71 | { 72 | return $this->SwooleMysql->{$property}; 73 | } 74 | 75 | } 76 | 77 | 78 | $http = new Swoole\Http\Server('0.0.0.0', 8082, SWOOLE_PROCESS); 79 | $http->set(['worker_num' => swoole_cpu_num() * 2]); 80 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 81 | 82 | static $cache = []; 83 | 84 | static $Pool; 85 | if ($Pool === NULL) { 86 | $Pool = new Pool; 87 | } 88 | 89 | if (empty($cache['test1_data'])) { 90 | $Connection = $Pool->get_connection(MysqlConnection::class); 91 | 92 | $stmt = $Connection->prepare("SELECT * FROM test1"); 93 | if ($stmt === FALSE) { 94 | print $Connection->connect_error; 95 | print $Connection->error; 96 | } 97 | $cache['test1_data'] = $stmt->execute(); 98 | $Pool->free_connection($Connection); 99 | } 100 | $data = $cache['test1_data']; 101 | 102 | $str = print_r($data, TRUE); 103 | 104 | 105 | $response->end($str); 106 | }); 107 | $http->start(); -------------------------------------------------------------------------------- /include/conn_settings.php: -------------------------------------------------------------------------------- 1 | $match) { 10 | if ( 11 | stripos($path, 'test') !== FALSE || 12 | strpos($path,'/bin/')!==FALSE || 13 | strpos($path,'soap')!==FALSE || 14 | strpos($path,'compatibility')!==FALSE || 15 | strpos($path,'Null.php')!==FALSE || 16 | strpos($path,'Int.php')!==FALSE || 17 | strpos($path,'Object.php')!==FALSE || 18 | strpos($path,'Float.php')!==FALSE || 19 | strpos($path,'build_phar')!==FALSE || 20 | strpos($path,'psalm-autoload.php')!==FALSE || 21 | strpos($path,'generate.php')!==FALSE || 22 | strpos($path,'.phpstorm.meta.php')!==FALSE || 23 | strpos($path,'phar-io')!==FALSE 24 | ) { 25 | continue; 26 | } 27 | require_once($path); 28 | } 29 | 30 | } 31 | 32 | function include_random_classes(int $number_of_classes) { 33 | $available_classes = require_once('../include/available_classes.php'); 34 | //print_r($available_classes); 35 | $available_classes = array_values($available_classes); 36 | for ($aa=0 ; $aa < $number_of_classes ; $aa++) { 37 | $r = rand(0, count($available_classes) - 1); 38 | $class_name = $available_classes[$r]; 39 | class_exists($class_name); 40 | //new ReflectionClass($class_name); 41 | } 42 | } 43 | 44 | function get_all_files(string $path) : array 45 | { 46 | $Directory = new \RecursiveDirectoryIterator($path); 47 | $Iterator = new \RecursiveIteratorIterator($Directory); 48 | $Regex = new \RegexIterator($Iterator, '/^.+\.php$/i', \RegexIterator::GET_MATCH); 49 | return array_keys(iterator_to_array($Regex)); 50 | } -------------------------------------------------------------------------------- /real_app_simulation/README.md: -------------------------------------------------------------------------------- 1 | # Real application simulation test 2 | 3 | This test combines [basic_class_load_multiple](./basic_class_load_multiple/) and 10 000 cache reads. 4 | In Swoole the cache is just a memory read, in Apache/mod_php this is APCu read. 5 | There is also a Pool class but this is not really used - only for the first connection. 6 | 7 | The results are: 8 | - Swoole 100 / 10 000 - Requests per second: **15195.12** 9 | - Apache/mod_php 100 / 10 000 - Requests per second: **228.51** 10 | - Swoole 100 / 10 000 - Requests per second: **15771.75** 11 | - Apache/mod_php 100 / 10 000 - Requests per second: **197.57** with **153 failed requests** 12 | - Swoole 1 000 / 10 000 - Requests per second: **14635.35** 13 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **failed, 1266 requests completed** 14 | 15 | This test really compares unserialization and APCu reads versus plain memory read. Because of this Apache shows much better results. 16 | 17 | #### Swoole 100 / 10 000 18 | ``` 19 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 20 | 21 | [...] 22 | 23 | Server Software: swoole-http-server 24 | Server Hostname: 192.168.0.233 25 | Server Port: 8082 26 | 27 | Document Path: / 28 | Document Length: 792 bytes 29 | 30 | Concurrency Level: 100 31 | Time taken for tests: 0.658 seconds 32 | Complete requests: 10000 33 | Failed requests: 0 34 | Write errors: 0 35 | Keep-Alive requests: 10000 36 | Total transferred: 9460000 bytes 37 | HTML transferred: 7920000 bytes 38 | Requests per second: 15195.12 [#/sec] (mean) 39 | Time per request: 6.581 [ms] (mean) 40 | Time per request: 0.066 [ms] (mean, across all concurrent requests) 41 | Transfer rate: 14037.68 [Kbytes/sec] received 42 | 43 | Connection Times (ms) 44 | min mean[+/-sd] median max 45 | Connect: 0 0 0.8 0 11 46 | Processing: 1 6 5.9 4 53 47 | Waiting: 1 6 5.9 4 53 48 | Total: 1 6 6.0 4 53 49 | 50 | Percentage of the requests served within a certain time (ms) 51 | 50% 4 52 | 66% 6 53 | 75% 7 54 | 80% 8 55 | 90% 15 56 | 95% 23 57 | 98% 24 58 | 99% 28 59 | 100% 53 (longest request) 60 | ``` 61 | #### Apache 100 / 10 000 62 | ``` 63 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation/apache.php 64 | 65 | [...] 66 | 67 | Server Software: Apache/2.4.25 68 | Server Hostname: 192.168.0.233 69 | Server Port: 8083 70 | 71 | Document Path: /swoole_tests/swoole-performance-tests/real_app_simulation/apache.php 72 | Document Length: 792 bytes 73 | 74 | Concurrency Level: 100 75 | Time taken for tests: 43.762 seconds 76 | Complete requests: 10000 77 | Failed requests: 0 78 | Write errors: 0 79 | Keep-Alive requests: 9973 80 | Total transferred: 10448837 bytes 81 | HTML transferred: 7920000 bytes 82 | Requests per second: 228.51 [#/sec] (mean) 83 | Time per request: 437.618 [ms] (mean) 84 | Time per request: 4.376 [ms] (mean, across all concurrent requests) 85 | Transfer rate: 233.17 [Kbytes/sec] received 86 | 87 | Connection Times (ms) 88 | min mean[+/-sd] median max 89 | Connect: 0 0 1.7 0 21 90 | Processing: 52 436 479.5 425 7077 91 | Waiting: 42 436 479.5 425 7077 92 | Total: 52 436 481.0 425 7098 93 | 94 | Percentage of the requests served within a certain time (ms) 95 | 50% 425 96 | 66% 444 97 | 75% 459 98 | 80% 468 99 | 90% 499 100 | 95% 529 101 | 98% 565 102 | 99% 616 103 | 100% 7098 (longest request) 104 | ``` 105 | #### Swoole 500 / 10 000 106 | ``` 107 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8082/ 108 | 109 | [...] 110 | 111 | Server Software: swoole-http-server 112 | Server Hostname: 192.168.0.233 113 | Server Port: 8082 114 | 115 | Document Path: / 116 | Document Length: 792 bytes 117 | 118 | Concurrency Level: 500 119 | Time taken for tests: 0.634 seconds 120 | Complete requests: 10000 121 | Failed requests: 0 122 | Write errors: 0 123 | Keep-Alive requests: 10000 124 | Total transferred: 9460000 bytes 125 | HTML transferred: 7920000 bytes 126 | Requests per second: 15771.75 [#/sec] (mean) 127 | Time per request: 31.702 [ms] (mean) 128 | Time per request: 0.063 [ms] (mean, across all concurrent requests) 129 | Transfer rate: 14570.39 [Kbytes/sec] received 130 | 131 | Connection Times (ms) 132 | min mean[+/-sd] median max 133 | Connect: 0 1 5.0 0 32 134 | Processing: 3 29 12.8 30 84 135 | Waiting: 1 29 12.8 30 84 136 | Total: 3 30 12.8 30 92 137 | 138 | Percentage of the requests served within a certain time (ms) 139 | 50% 30 140 | 66% 33 141 | 75% 36 142 | 80% 39 143 | 90% 48 144 | 95% 54 145 | 98% 58 146 | 99% 62 147 | 100% 92 (longest request) 148 | ``` 149 | #### Apache 500 / 10 000 150 | ``` 151 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -s 120 -c 500 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation/apache.php 152 | 153 | [...] 154 | 155 | Server Software: Apache/2.4.25 156 | Server Hostname: 192.168.0.233 157 | Server Port: 8083 158 | 159 | Document Path: /swoole_tests/swoole-performance-tests/real_app_simulation/apache.php 160 | Document Length: 792 bytes 161 | 162 | Concurrency Level: 500 163 | Time taken for tests: 50.616 seconds 164 | Complete requests: 10000 165 | Failed requests: 153 166 | (Connect: 0, Receive: 0, Length: 153, Exceptions: 0) 167 | Write errors: 0 168 | Keep-Alive requests: 9847 169 | Total transferred: 10290462 bytes 170 | HTML transferred: 7798824 bytes 171 | Requests per second: 197.57 [#/sec] (mean) 172 | Time per request: 2530.807 [ms] (mean) 173 | Time per request: 5.062 [ms] (mean, across all concurrent requests) 174 | Transfer rate: 198.54 [Kbytes/sec] received 175 | 176 | Connection Times (ms) 177 | min mean[+/-sd] median max 178 | Connect: 0 1 5.1 0 38 179 | Processing: 33 1697 5034.9 1067 50532 180 | Waiting: 33 1639 5018.2 1065 50532 181 | Total: 61 1698 5038.8 1067 50567 182 | 183 | Percentage of the requests served within a certain time (ms) 184 | 50% 1067 185 | 66% 1181 186 | 75% 1254 187 | 80% 1299 188 | 90% 1439 189 | 95% 1596 190 | 98% 5006 191 | 99% 21089 192 | 100% 50567 (longest request) 193 | ``` 194 | #### Swoole 1 000 / 10 000 195 | ``` 196 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8082/ 197 | 198 | [...] 199 | 200 | Server Software: swoole-http-server 201 | Server Hostname: 192.168.0.233 202 | Server Port: 8082 203 | 204 | Document Path: / 205 | Document Length: 792 bytes 206 | 207 | Concurrency Level: 1000 208 | Time taken for tests: 0.683 seconds 209 | Complete requests: 10000 210 | Failed requests: 0 211 | Write errors: 0 212 | Keep-Alive requests: 10000 213 | Total transferred: 9460000 bytes 214 | HTML transferred: 7920000 bytes 215 | Requests per second: 14635.35 [#/sec] (mean) 216 | Time per request: 68.328 [ms] (mean) 217 | Time per request: 0.068 [ms] (mean, across all concurrent requests) 218 | Transfer rate: 13520.55 [Kbytes/sec] received 219 | 220 | Connection Times (ms) 221 | min mean[+/-sd] median max 222 | Connect: 0 5 14.5 0 71 223 | Processing: 12 57 21.7 59 155 224 | Waiting: 1 57 21.7 59 155 225 | Total: 14 61 20.4 61 155 226 | 227 | Percentage of the requests served within a certain time (ms) 228 | 50% 61 229 | 66% 68 230 | 75% 75 231 | 80% 78 232 | 90% 87 233 | 95% 92 234 | 98% 104 235 | 99% 115 236 | 100% 155 (longest request) 237 | ``` 238 | #### Apache 1 000 / 10 000 239 | ``` 240 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation/apache.php 241 | This is ApacheBench, Version 2.3 <$Revision: 1430300 $> 242 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 243 | Licensed to The Apache Software Foundation, http://www.apache.org/ 244 | 245 | Benchmarking 192.168.0.233 (be patient) 246 | Completed 1000 requests 247 | apr_socket_recv: Connection reset by peer (104) 248 | Total of 1266 requests completed 249 | ``` -------------------------------------------------------------------------------- /real_app_simulation/apache.php: -------------------------------------------------------------------------------- 1 | connect_error) 18 | { 19 | die("$mysqli->connect_errno: $mysqli->connect_error"); 20 | } 21 | 22 | $stmt = $mysqli->prepare("SELECT * FROM test1"); 23 | $stmt->execute(); 24 | $result = $stmt->get_result(); 25 | $data = []; 26 | while($row = $result->fetch_assoc()) { 27 | $data[] = $row; 28 | } 29 | 30 | apcu_add('test1_data', $data); 31 | } 32 | } 33 | 34 | print_r($data); 35 | 36 | 37 | -------------------------------------------------------------------------------- /real_app_simulation/swoole.php: -------------------------------------------------------------------------------- 1 | available_connections)) { 21 | $this->initialize_connections($connection_class); 22 | } 23 | 24 | $Connection = $this->available_connections[$connection_class]->pop();//blocks and waits until one is available if there are no available ones 25 | 26 | return $Connection; 27 | } 28 | 29 | public function free_connection(ConnectionInterface $Connection) : void 30 | { 31 | $connection_class = get_class($Connection); 32 | 33 | $this->available_connections[$connection_class]->push($Connection); 34 | } 35 | 36 | private function initialize_connections(string $connection_class) : void 37 | { 38 | $this->available_connections[$connection_class] = new \Swoole\Coroutine\Channel(self::MAX_CONNECTIONS); 39 | for ($aa = 0; $aa < self::MAX_CONNECTIONS ; $aa++) { 40 | $Connection = new $connection_class(); 41 | $this->available_connections[$connection_class]->push($Connection); 42 | } 43 | } 44 | 45 | } 46 | 47 | interface ConnectionInterface 48 | { 49 | } 50 | 51 | class MysqlConnection implements ConnectionInterface 52 | { 53 | 54 | private const CONNECTION_SETTINGS = [ 55 | 'host' => MYSQL_HOST, 56 | 'port' => MYSQL_PORT, 57 | 'user' => MYSQL_USER, 58 | 'password' => MYSQL_PASS, 59 | 'database' => MYSQL_DB, 60 | ]; 61 | 62 | private $SwooleMysql; 63 | 64 | public function __construct() 65 | { 66 | $this->SwooleMysql = new Swoole\Coroutine\MySQL(); 67 | $this->SwooleMysql->connect(self::CONNECTION_SETTINGS); 68 | } 69 | 70 | public function __call(string $method, array $args) 71 | { 72 | return call_user_func_array([$this->SwooleMysql, $method], $args); 73 | } 74 | 75 | public function __get(string $property) 76 | { 77 | return $this->SwooleMysql->{$property}; 78 | } 79 | 80 | } 81 | 82 | 83 | $http = new Swoole\Http\Server('0.0.0.0', 8082, SWOOLE_PROCESS); 84 | $http->set(['worker_num' => swoole_cpu_num() * 2]); 85 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 86 | 87 | static $cache = []; 88 | 89 | static $Pool; 90 | if ($Pool === NULL) { 91 | $Pool = new Pool; 92 | } 93 | 94 | 95 | for ($aa = 0 ; $aa < 10000; $aa++) { 96 | if (empty($cache['test1_data'])) { 97 | $Connection = $Pool->get_connection(MysqlConnection::class); 98 | 99 | $stmt = $Connection->prepare("SELECT * FROM test1"); 100 | if ($stmt === FALSE) { 101 | print $Connection->connect_error; 102 | print $Connection->error; 103 | } 104 | $cache['test1_data'] = $stmt->execute(); 105 | $Pool->free_connection($Connection); 106 | } 107 | $data = $cache['test1_data']; 108 | } 109 | 110 | $str = print_r($data, TRUE); 111 | 112 | 113 | $response->end($str); 114 | }); 115 | $http->start(); -------------------------------------------------------------------------------- /real_app_simulation_with_files/README.md: -------------------------------------------------------------------------------- 1 | # Real application simulation with files 2 | 3 | This test is [real_app_simluation](../real_app_simulation/) with 10 file reads and 10 file writes. 4 | 5 | The results are: 6 | - Swoole 100 / 10 000 - Requests per second: **845.97** 7 | - Apache/mod_php 100 / 10 000 - Requests per second: **220.27** 8 | - Swoole 500 / 10 000 - Requests per second: **1372.28** 9 | - Apache/mod_php 500 / 10 000 - Requests per second: **196.54** with **222 failed requests** 10 | - Swoole 1 000 / 10 000 - Requests per second: **1426.92** 11 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **failed, 1339 requests completed** 12 | 13 | When running this test please make sure the ./files directory is writable by Swoole and Apache. 14 | 15 | #### Swoole 100 / 10 000 16 | ``` 17 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 18 | 19 | [...] 20 | 21 | Server Software: swoole-http-server 22 | Server Hostname: 192.168.0.233 23 | Server Port: 8082 24 | 25 | Document Path: / 26 | Document Length: 792 bytes 27 | 28 | Concurrency Level: 100 29 | Time taken for tests: 11.821 seconds 30 | Complete requests: 10000 31 | Failed requests: 0 32 | Write errors: 0 33 | Keep-Alive requests: 10000 34 | Total transferred: 9460000 bytes 35 | HTML transferred: 7920000 bytes 36 | Requests per second: 845.97 [#/sec] (mean) 37 | Time per request: 118.208 [ms] (mean) 38 | Time per request: 1.182 [ms] (mean, across all concurrent requests) 39 | Transfer rate: 781.53 [Kbytes/sec] received 40 | 41 | Connection Times (ms) 42 | min mean[+/-sd] median max 43 | Connect: 0 0 1.0 0 12 44 | Processing: 5 118 54.0 118 305 45 | Waiting: 5 118 54.0 118 305 46 | Total: 5 118 53.9 118 305 47 | 48 | Percentage of the requests served within a certain time (ms) 49 | 50% 118 50 | 66% 147 51 | 75% 161 52 | 80% 170 53 | 90% 189 54 | 95% 203 55 | 98% 218 56 | 99% 230 57 | 100% 305 (longest request) 58 | ``` 59 | #### Apache 100 / 10 000 60 | ``` 61 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation_with_files/apache.php 62 | 63 | [...] 64 | 65 | Server Software: Apache/2.4.25 66 | Server Hostname: 192.168.0.233 67 | Server Port: 8083 68 | 69 | Document Path: /swoole_tests/swoole-performance-tests/real_app_simulation_with_files/apache.php 70 | Document Length: 792 bytes 71 | 72 | Concurrency Level: 100 73 | Time taken for tests: 45.398 seconds 74 | Complete requests: 10000 75 | Failed requests: 0 76 | Write errors: 0 77 | Keep-Alive requests: 9930 78 | Total transferred: 10446919 bytes 79 | HTML transferred: 7920000 bytes 80 | Requests per second: 220.27 [#/sec] (mean) 81 | Time per request: 453.983 [ms] (mean) 82 | Time per request: 4.540 [ms] (mean, across all concurrent requests) 83 | Transfer rate: 224.72 [Kbytes/sec] received 84 | 85 | Connection Times (ms) 86 | min mean[+/-sd] median max 87 | Connect: 0 0 1.9 0 22 88 | Processing: 71 453 219.2 442 5504 89 | Waiting: 60 452 219.2 442 5504 90 | Total: 71 453 220.1 443 5526 91 | 92 | Percentage of the requests served within a certain time (ms) 93 | 50% 443 94 | 66% 481 95 | 75% 507 96 | 80% 522 97 | 90% 566 98 | 95% 601 99 | 98% 642 100 | 99% 681 101 | 100% 5526 (longest request) 102 | ``` 103 | 104 | #### Swoole 500 / 10 000 105 | ``` 106 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8082/ 107 | 108 | [...] 109 | 110 | Server Software: swoole-http-server 111 | Server Hostname: 192.168.0.233 112 | Server Port: 8082 113 | 114 | Document Path: / 115 | Document Length: 792 bytes 116 | 117 | Concurrency Level: 500 118 | Time taken for tests: 7.287 seconds 119 | Complete requests: 10000 120 | Failed requests: 0 121 | Write errors: 0 122 | Keep-Alive requests: 10000 123 | Total transferred: 9460000 bytes 124 | HTML transferred: 7920000 bytes 125 | Requests per second: 1372.28 [#/sec] (mean) 126 | Time per request: 364.357 [ms] (mean) 127 | Time per request: 0.729 [ms] (mean, across all concurrent requests) 128 | Transfer rate: 1267.75 [Kbytes/sec] received 129 | 130 | Connection Times (ms) 131 | min mean[+/-sd] median max 132 | Connect: 0 2 8.2 0 55 133 | Processing: 61 359 178.6 315 1066 134 | Waiting: 21 359 178.6 315 1066 135 | Total: 71 361 177.8 323 1066 136 | 137 | Percentage of the requests served within a certain time (ms) 138 | 50% 323 139 | 66% 421 140 | 75% 486 141 | 80% 527 142 | 90% 631 143 | 95% 694 144 | 98% 757 145 | 99% 794 146 | 100% 1066 (longest request) 147 | ``` 148 | #### Apache 500 / 10 000 149 | ``` 150 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation_with_files/apache.php 151 | 152 | [...] 153 | 154 | Server Software: Apache/2.4.25 155 | Server Hostname: 192.168.0.233 156 | Server Port: 8083 157 | 158 | Document Path: /swoole_tests/swoole-performance-tests/real_app_simulation_with_files/apache.php 159 | Document Length: 792 bytes 160 | 161 | Concurrency Level: 500 162 | Time taken for tests: 50.881 seconds 163 | Complete requests: 10000 164 | Failed requests: 222 165 | (Connect: 0, Receive: 0, Length: 222, Exceptions: 0) 166 | Write errors: 0 167 | Keep-Alive requests: 9778 168 | Total transferred: 10218288 bytes 169 | HTML transferred: 7744176 bytes 170 | Requests per second: 196.54 [#/sec] (mean) 171 | Time per request: 2544.066 [ms] (mean) 172 | Time per request: 5.088 [ms] (mean, across all concurrent requests) 173 | Transfer rate: 196.12 [Kbytes/sec] received 174 | 175 | Connection Times (ms) 176 | min mean[+/-sd] median max 177 | Connect: 0 1 6.8 0 58 178 | Processing: 110 1389 2430.5 1169 50745 179 | Waiting: 51 1301 2369.2 1160 50745 180 | Total: 110 1390 2433.6 1170 50802 181 | 182 | Percentage of the requests served within a certain time (ms) 183 | 50% 1170 184 | 66% 1262 185 | 75% 1332 186 | 80% 1388 187 | 90% 1553 188 | 95% 1730 189 | 98% 5005 190 | 99% 5007 191 | 100% 50802 (longest request) 192 | ``` 193 | 194 | #### Swoole 1 000 / 10 000 195 | ``` 196 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8082/ 197 | 198 | [...] 199 | 200 | Server Software: swoole-http-server 201 | Server Hostname: 192.168.0.233 202 | Server Port: 8082 203 | 204 | Document Path: / 205 | Document Length: 792 bytes 206 | 207 | Concurrency Level: 1000 208 | Time taken for tests: 7.008 seconds 209 | Complete requests: 10000 210 | Failed requests: 0 211 | Write errors: 0 212 | Keep-Alive requests: 10000 213 | Total transferred: 9460000 bytes 214 | HTML transferred: 7920000 bytes 215 | Requests per second: 1426.92 [#/sec] (mean) 216 | Time per request: 700.808 [ms] (mean) 217 | Time per request: 0.701 [ms] (mean, across all concurrent requests) 218 | Transfer rate: 1318.23 [Kbytes/sec] received 219 | 220 | Connection Times (ms) 221 | min mean[+/-sd] median max 222 | Connect: 0 7 22.7 0 100 223 | Processing: 47 679 272.6 653 1401 224 | Waiting: 15 679 272.6 653 1401 225 | Total: 105 687 264.3 654 1401 226 | 227 | Percentage of the requests served within a certain time (ms) 228 | 50% 654 229 | 66% 806 230 | 75% 884 231 | 80% 934 232 | 90% 1085 233 | 95% 1150 234 | 98% 1216 235 | 99% 1249 236 | 100% 1401 (longest request) 237 | ``` 238 | #### Apache 1 000 / 10 000 239 | ``` 240 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation_with_files/apache.php 241 | This is ApacheBench, Version 2.3 <$Revision: 1430300 $> 242 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 243 | Licensed to The Apache Software Foundation, http://www.apache.org/ 244 | 245 | Benchmarking 192.168.0.233 (be patient) 246 | Completed 1000 requests 247 | apr_socket_recv: Connection reset by peer (104) 248 | Total of 1339 requests completed 249 | ``` -------------------------------------------------------------------------------- /real_app_simulation_with_files/apache.php: -------------------------------------------------------------------------------- 1 | connect_error) 22 | { 23 | die("$mysqli->connect_errno: $mysqli->connect_error"); 24 | } 25 | 26 | $stmt = $mysqli->prepare("SELECT * FROM test1"); 27 | $stmt->execute(); 28 | $result = $stmt->get_result(); 29 | $data = []; 30 | while($row = $result->fetch_assoc()) { 31 | $data[] = $row; 32 | } 33 | 34 | apcu_add('test1_data', $data); 35 | } 36 | } 37 | 38 | //write some files 39 | $file_content = 'some content here'; 40 | for( $aa = 0; $aa < 10; $aa++) { 41 | $file_name = './files/apache'.$aa.'.txt'; 42 | file_put_contents($file_name, $file_content); 43 | } 44 | 45 | //read some files 46 | for( $aa = 0; $aa < 10; $aa++) { 47 | $file_name = './files/apache'.$aa.'.txt'; 48 | $file_content = file_get_contents($file_name); 49 | } 50 | 51 | print_r($data); 52 | 53 | 54 | -------------------------------------------------------------------------------- /real_app_simulation_with_files/swoole.php: -------------------------------------------------------------------------------- 1 | available_connections)) { 25 | $this->initialize_connections($connection_class); 26 | } 27 | 28 | $Connection = $this->available_connections[$connection_class]->pop();//blocks and waits until one is available if there are no available ones 29 | 30 | return $Connection; 31 | } 32 | 33 | public function free_connection(ConnectionInterface $Connection) : void 34 | { 35 | $connection_class = get_class($Connection); 36 | 37 | $this->available_connections[$connection_class]->push($Connection); 38 | } 39 | 40 | private function initialize_connections(string $connection_class) : void 41 | { 42 | $this->available_connections[$connection_class] = new \Swoole\Coroutine\Channel(self::MAX_CONNECTIONS); 43 | for ($aa = 0; $aa < self::MAX_CONNECTIONS ; $aa++) { 44 | $Connection = new $connection_class(); 45 | $this->available_connections[$connection_class]->push($Connection); 46 | } 47 | } 48 | 49 | } 50 | 51 | interface ConnectionInterface 52 | { 53 | } 54 | 55 | class MysqlConnection implements ConnectionInterface 56 | { 57 | 58 | private const CONNECTION_SETTINGS = [ 59 | 'host' => MYSQL_HOST, 60 | 'port' => MYSQL_PORT, 61 | 'user' => MYSQL_USER, 62 | 'password' => MYSQL_PASS, 63 | 'database' => MYSQL_DB, 64 | ]; 65 | 66 | private $SwooleMysql; 67 | 68 | public function __construct() 69 | { 70 | $this->SwooleMysql = new Swoole\Coroutine\MySQL(); 71 | $this->SwooleMysql->connect(self::CONNECTION_SETTINGS); 72 | } 73 | 74 | public function __call(string $method, array $args) 75 | { 76 | return call_user_func_array([$this->SwooleMysql, $method], $args); 77 | } 78 | 79 | public function __get(string $property) 80 | { 81 | return $this->SwooleMysql->{$property}; 82 | } 83 | 84 | } 85 | 86 | 87 | $http = new Swoole\Http\Server('0.0.0.0', 8082, SWOOLE_PROCESS); 88 | $http->set(['worker_num' => swoole_cpu_num() * 2]); 89 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 90 | 91 | static $cache = []; 92 | 93 | static $Pool; 94 | if ($Pool === NULL) { 95 | $Pool = new Pool; 96 | } 97 | 98 | //loop through many cached objects 99 | for ($aa = 0 ; $aa < 10000; $aa++) { 100 | if (empty($cache['test1_data'])) { 101 | $Connection = $Pool->get_connection(MysqlConnection::class); 102 | 103 | $stmt = $Connection->prepare("SELECT * FROM test1"); 104 | if ($stmt === FALSE) { 105 | print $Connection->connect_error; 106 | print $Connection->error; 107 | } 108 | $cache['test1_data'] = $stmt->execute(); 109 | $Pool->free_connection($Connection); 110 | } 111 | $data = $cache['test1_data']; 112 | } 113 | //write some files 114 | $file_content = 'some content here'; 115 | for( $aa = 0; $aa < 10; $aa++) { 116 | $file_name = './files/swoole_'.$aa.'.txt'; 117 | Swoole\Coroutine\System::writeFile($file_name, $file_content); 118 | } 119 | 120 | //read some files 121 | for( $aa = 0; $aa < 10; $aa++) { 122 | $file_name = './files/swoole_'.$aa.'.txt'; 123 | $file_content = Swoole\Coroutine\System::readFile($file_name); 124 | } 125 | 126 | 127 | $str = print_r($data, TRUE); 128 | 129 | 130 | $response->end($str); 131 | }); 132 | $http->start(); -------------------------------------------------------------------------------- /real_app_simulation_with_files_and_connections/README.md: -------------------------------------------------------------------------------- 1 | # Real application simulation with files 2 | 3 | This test is [real_app_simluation_with_files](../real_app_simulation_with_files/) with 20 db reads with connection pool 4 | 5 | The results are: 6 | - Swoole 100 / 10 000 - Requests per second: **285.91** 7 | - Apache/mod_php 100 / 10 000 - Requests per second: **141.24** 8 | - Swoole 500 / 10 000 - Requests per second: **285.32** 9 | - Apache/mod_php 500 / 10 000 - Requests per second: **115.82** with **249 failed requests** 10 | - Swoole 1 000 / 10 000 - Requests per second: **314.33** 11 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **failed, 1159 requests completed** 12 | 13 | When running this test please make sure the ./files directory is writable by Swoole and Apache. 14 | 15 | It is important to note that Swoole can execute the file reads and he queries in parallel (with sub-coroutines) is these are independent of each other. 16 | The given example is not taking advantage of this (in real world application at least some of the queries will be independent and can be run in parallel). 17 | 18 | #### Swoole 100 / 10 000 19 | ``` 20 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 21 | 22 | [...] 23 | 24 | Server Software: swoole-http-server 25 | Server Hostname: 192.168.0.233 26 | Server Port: 8082 27 | 28 | Document Path: / 29 | Document Length: 792 bytes 30 | 31 | Concurrency Level: 100 32 | Time taken for tests: 34.976 seconds 33 | Complete requests: 10000 34 | Failed requests: 0 35 | Write errors: 0 36 | Keep-Alive requests: 10000 37 | Total transferred: 9460000 bytes 38 | HTML transferred: 7920000 bytes 39 | Requests per second: 285.91 [#/sec] (mean) 40 | Time per request: 349.759 [ms] (mean) 41 | Time per request: 3.498 [ms] (mean, across all concurrent requests) 42 | Transfer rate: 264.13 [Kbytes/sec] received 43 | 44 | Connection Times (ms) 45 | min mean[+/-sd] median max 46 | Connect: 0 0 0.9 0 12 47 | Processing: 224 346 84.2 370 995 48 | Waiting: 224 346 84.2 370 995 49 | Total: 224 346 84.5 370 1002 50 | 51 | Percentage of the requests served within a certain time (ms) 52 | 50% 370 53 | 66% 398 54 | 75% 410 55 | 80% 418 56 | 90% 436 57 | 95% 450 58 | 98% 478 59 | 99% 576 60 | 100% 1002 (longest request) 61 | ``` 62 | #### Apache 100 / 10 000 63 | ``` 64 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections/apache.php 65 | 66 | [...] 67 | 68 | Server Software: Apache/2.4.25 69 | Server Hostname: 192.168.0.233 70 | Server Port: 8083 71 | 72 | Document Path: /swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections/apache.php 73 | Document Length: 3282 bytes 74 | 75 | Concurrency Level: 100 76 | Time taken for tests: 70.801 seconds 77 | Complete requests: 10000 78 | Failed requests: 0 79 | Write errors: 0 80 | Keep-Alive requests: 9956 81 | Total transferred: 35357722 bytes 82 | HTML transferred: 32820000 bytes 83 | Requests per second: 141.24 [#/sec] (mean) 84 | Time per request: 708.011 [ms] (mean) 85 | Time per request: 7.080 [ms] (mean, across all concurrent requests) 86 | Transfer rate: 487.69 [Kbytes/sec] received 87 | 88 | Connection Times (ms) 89 | min mean[+/-sd] median max 90 | Connect: 0 0 2.1 0 25 91 | Processing: 240 703 132.3 732 1290 92 | Waiting: 240 703 132.3 732 1290 93 | Total: 240 703 132.8 732 1314 94 | 95 | Percentage of the requests served within a certain time (ms) 96 | 50% 732 97 | 66% 759 98 | 75% 774 99 | 80% 784 100 | 90% 812 101 | 95% 840 102 | 98% 866 103 | 99% 898 104 | 100% 1314 (longest request) 105 | 106 | ``` 107 | #### Swoole 500 / 10 000 108 | ``` 109 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8082/ 110 | 111 | [...] 112 | 113 | Server Software: swoole-http-server 114 | Server Hostname: 192.168.0.233 115 | Server Port: 8082 116 | 117 | Document Path: / 118 | Document Length: 792 bytes 119 | 120 | Concurrency Level: 500 121 | Time taken for tests: 35.048 seconds 122 | Complete requests: 10000 123 | Failed requests: 0 124 | Write errors: 0 125 | Keep-Alive requests: 10000 126 | Total transferred: 9460000 bytes 127 | HTML transferred: 7920000 bytes 128 | Requests per second: 285.32 [#/sec] (mean) 129 | Time per request: 1752.397 [ms] (mean) 130 | Time per request: 3.505 [ms] (mean, across all concurrent requests) 131 | Transfer rate: 263.59 [Kbytes/sec] received 132 | 133 | Connection Times (ms) 134 | min mean[+/-sd] median max 135 | Connect: 0 3 39.6 0 1003 136 | Processing: 269 1691 194.0 1691 4027 137 | Waiting: 245 1691 194.1 1691 4027 138 | Total: 280 1694 194.7 1692 4079 139 | 140 | Percentage of the requests served within a certain time (ms) 141 | 50% 1692 142 | 66% 1727 143 | 75% 1751 144 | 80% 1770 145 | 90% 1827 146 | 95% 1883 147 | 98% 1953 148 | 99% 2068 149 | 100% 4079 (longest request) 150 | ``` 151 | #### Apache 500 / 10 000 152 | ``` 153 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections/apache.php 154 | 155 | [...] 156 | 157 | Server Software: Apache/2.4.25 158 | Server Hostname: 192.168.0.233 159 | Server Port: 8083 160 | 161 | Document Path: /swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections/apache.php 162 | Document Length: 3282 bytes 163 | 164 | Concurrency Level: 500 165 | Time taken for tests: 86.339 seconds 166 | Complete requests: 10000 167 | Failed requests: 249 168 | (Connect: 0, Receive: 0, Length: 249, Exceptions: 0) 169 | Write errors: 0 170 | Keep-Alive requests: 9756 171 | Total transferred: 34497472 bytes 172 | HTML transferred: 32019192 bytes 173 | Requests per second: 115.82 [#/sec] (mean) 174 | Time per request: 4316.953 [ms] (mean) 175 | Time per request: 8.634 [ms] (mean, across all concurrent requests) 176 | Transfer rate: 390.19 [Kbytes/sec] received 177 | 178 | Connection Times (ms) 179 | min mean[+/-sd] median max 180 | Connect: 0 5 120.2 0 3007 181 | Processing: 272 2179 1009.8 2322 10326 182 | Waiting: 259 2101 916.7 2313 10326 183 | Total: 272 2184 1041.9 2322 10373 184 | 185 | Percentage of the requests served within a certain time (ms) 186 | 50% 2322 187 | 66% 2448 188 | 75% 2511 189 | 80% 2547 190 | 90% 2676 191 | 95% 2807 192 | 98% 5005 193 | 99% 5922 194 | 100% 10373 (longest request) 195 | ``` 196 | #### Swoole 1 000 / 10 000 197 | ``` 198 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8082/ 199 | 200 | [...] 201 | 202 | Server Software: swoole-http-server 203 | Server Hostname: 192.168.0.233 204 | Server Port: 8082 205 | 206 | Document Path: / 207 | Document Length: 792 bytes 208 | 209 | Concurrency Level: 1000 210 | Time taken for tests: 31.813 seconds 211 | Complete requests: 10000 212 | Failed requests: 0 213 | Write errors: 0 214 | Keep-Alive requests: 10000 215 | Total transferred: 9460000 bytes 216 | HTML transferred: 7920000 bytes 217 | Requests per second: 314.33 [#/sec] (mean) 218 | Time per request: 3181.322 [ms] (mean) 219 | Time per request: 3.181 [ms] (mean, across all concurrent requests) 220 | Transfer rate: 290.39 [Kbytes/sec] received 221 | 222 | Connection Times (ms) 223 | min mean[+/-sd] median max 224 | Connect: 0 6 19.9 0 99 225 | Processing: 336 2989 431.9 3058 3818 226 | Waiting: 237 2989 431.9 3058 3818 227 | Total: 336 2995 417.3 3060 3904 228 | 229 | Percentage of the requests served within a certain time (ms) 230 | 50% 3060 231 | 66% 3116 232 | 75% 3152 233 | 80% 3173 234 | 90% 3260 235 | 95% 3341 236 | 98% 3441 237 | 99% 3499 238 | 100% 3904 (longest request) 239 | ``` 240 | #### Apache 1 000 / 10 000 241 | ``` 242 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -s 120 -c 1000 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections/apache.php 243 | This is ApacheBench, Version 2.3 <$Revision: 1430300 $> 244 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 245 | Licensed to The Apache Software Foundation, http://www.apache.org/ 246 | 247 | Benchmarking 192.168.0.233 (be patient) 248 | Completed 1000 requests 249 | apr_socket_recv: Connection reset by peer (104) 250 | Total of 1159 requests completed 251 | ``` -------------------------------------------------------------------------------- /real_app_simulation_with_files_and_connections/apache.php: -------------------------------------------------------------------------------- 1 | connect_error) 22 | { 23 | die("$mysqli->connect_errno: $mysqli->connect_error"); 24 | } 25 | 26 | $stmt = $mysqli->prepare("SELECT * FROM test1"); 27 | $stmt->execute(); 28 | $result = $stmt->get_result(); 29 | $data = []; 30 | while($row = $result->fetch_assoc()) { 31 | $data[] = $row; 32 | } 33 | 34 | apcu_add('test1_data', $data); 35 | } 36 | } 37 | 38 | //write some files 39 | $file_content = 'some content here'; 40 | for( $aa = 0; $aa < 10; $aa++) { 41 | $file_name = './files/apache'.$aa.'.txt'; 42 | file_put_contents($file_name, $file_content); 43 | } 44 | 45 | //read some files 46 | for( $aa = 0; $aa < 10; $aa++) { 47 | $file_name = './files/apache'.$aa.'.txt'; 48 | $file_content = file_get_contents($file_name); 49 | } 50 | 51 | //do some db reads 52 | $mysqli = new mysqli("p:".MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB); 53 | for( $aa = 0; $aa < 20; $aa++) { 54 | $stmt = $mysqli->prepare("SELECT SLEEP(0.01)");//simulate a time consuming query 55 | $stmt->execute(); 56 | $result = $stmt->get_result(); 57 | $sql_data = []; 58 | while($row = $result->fetch_assoc()) { 59 | $sql_data[] = $row; 60 | } 61 | } 62 | 63 | print_r($data); 64 | 65 | 66 | -------------------------------------------------------------------------------- /real_app_simulation_with_files_and_connections/swoole.php: -------------------------------------------------------------------------------- 1 | available_connections)) { 25 | $this->initialize_connections($connection_class); 26 | } 27 | 28 | $Connection = $this->available_connections[$connection_class]->pop();//blocks and waits until one is available if there are no available ones 29 | 30 | return $Connection; 31 | } 32 | 33 | public function free_connection(ConnectionInterface $Connection) : void 34 | { 35 | $connection_class = get_class($Connection); 36 | 37 | $this->available_connections[$connection_class]->push($Connection); 38 | } 39 | 40 | private function initialize_connections(string $connection_class) : void 41 | { 42 | $this->available_connections[$connection_class] = new \Swoole\Coroutine\Channel(self::MAX_CONNECTIONS); 43 | for ($aa = 0; $aa < self::MAX_CONNECTIONS ; $aa++) { 44 | $Connection = new $connection_class(); 45 | $this->available_connections[$connection_class]->push($Connection); 46 | } 47 | } 48 | 49 | } 50 | 51 | interface ConnectionInterface 52 | { 53 | } 54 | 55 | class MysqlConnection implements ConnectionInterface 56 | { 57 | 58 | private const CONNECTION_SETTINGS = [ 59 | 'host' => MYSQL_HOST, 60 | 'port' => MYSQL_PORT, 61 | 'user' => MYSQL_USER, 62 | 'password' => MYSQL_PASS, 63 | 'database' => MYSQL_DB, 64 | ]; 65 | 66 | private $SwooleMysql; 67 | 68 | public function __construct() 69 | { 70 | $this->SwooleMysql = new Swoole\Coroutine\MySQL(); 71 | $this->SwooleMysql->connect(self::CONNECTION_SETTINGS); 72 | } 73 | 74 | public function __call(string $method, array $args) 75 | { 76 | return call_user_func_array([$this->SwooleMysql, $method], $args); 77 | } 78 | 79 | public function __get(string $property) 80 | { 81 | return $this->SwooleMysql->{$property}; 82 | } 83 | 84 | } 85 | 86 | 87 | $http = new Swoole\Http\Server('0.0.0.0', 8082, SWOOLE_PROCESS); 88 | $http->set(['worker_num' => swoole_cpu_num() * 2]); 89 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 90 | 91 | static $cache = []; 92 | 93 | static $Pool; 94 | if ($Pool === NULL) { 95 | $Pool = new Pool; 96 | } 97 | 98 | //loop through many cached objects 99 | for ($aa = 0 ; $aa < 10000; $aa++) { 100 | if (empty($cache['test1_data'])) { 101 | $Connection = $Pool->get_connection(MysqlConnection::class); 102 | 103 | $stmt = $Connection->prepare("SELECT * FROM test1"); 104 | if ($stmt === FALSE) { 105 | print $Connection->connect_error; 106 | print $Connection->error; 107 | } 108 | $cache['test1_data'] = $stmt->execute(); 109 | $Pool->free_connection($Connection); 110 | } 111 | $data = $cache['test1_data']; 112 | } 113 | 114 | //write some files 115 | $file_content = 'some content here'; 116 | for( $aa = 0; $aa < 10; $aa++) { 117 | $file_name = './files/swoole_'.$aa.'.txt'; 118 | Swoole\Coroutine\System::writeFile($file_name, $file_content); 119 | } 120 | 121 | //read some files 122 | for( $aa = 0; $aa < 10; $aa++) { 123 | $file_name = './files/swoole_'.$aa.'.txt'; 124 | $file_content = Swoole\Coroutine\System::readFile($file_name); 125 | } 126 | 127 | //do some DB reads 128 | $Connection = $Pool->get_connection(MysqlConnection::class); 129 | for ($aa = 0; $aa < 20; $aa++) { 130 | $stmt = $Connection->prepare("SELECT SLEEP(0.01)");//simulate a time consuming query 131 | $sql_data = $stmt->execute(); 132 | } 133 | $Pool->free_connection($Connection); 134 | 135 | 136 | $str = print_r($data, TRUE); 137 | 138 | 139 | $response->end($str); 140 | }); 141 | $http->start(); -------------------------------------------------------------------------------- /real_app_simulation_with_files_and_connections_simpler/README.md: -------------------------------------------------------------------------------- 1 | # Real application simulation with files 2 | 3 | This test is a simpler version of [real_app_simluation_with_files_with_connections](../real_app_simluation_with_files_with_connections/) with the following changes: 4 | - included classes: 50 5 | - cache reads: 1000 6 | - file reads: 1 7 | - file writes: 1 8 | - DB queries: 3 9 | 10 | This test perhaps is the closest one to a real world application. In such an application most of the data will be cached with few file reads or DB queries. 11 | 12 | The results are: 13 | - Swoole 100 / 10 000 - Requests per second: **1919.86** 14 | - Apache/mod_php 100 / 10 000 - Requests per second: **1194.24** 15 | - Swoole 500 / 10 000 - Requests per second: **1824.30** 16 | - Apache/mod_php 500 / 10 000 - Requests per second: **723.21** with **244 failed requests** 17 | - Swoole 1 000 / 10 000 - Requests per second: **1956.75** 18 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **702.33** with **256 failed requests** 19 | 20 | 21 | #### Swoole 100 / 10 000 22 | ``` 23 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 24 | 25 | [...] 26 | 27 | Server Software: swoole-http-server 28 | Server Hostname: 192.168.0.233 29 | Server Port: 8082 30 | 31 | Document Path: / 32 | Document Length: 792 bytes 33 | 34 | Concurrency Level: 100 35 | Time taken for tests: 5.209 seconds 36 | Complete requests: 10000 37 | Failed requests: 0 38 | Write errors: 0 39 | Keep-Alive requests: 10000 40 | Total transferred: 9460000 bytes 41 | HTML transferred: 7920000 bytes 42 | Requests per second: 1919.86 [#/sec] (mean) 43 | Time per request: 52.087 [ms] (mean) 44 | Time per request: 0.521 [ms] (mean, across all concurrent requests) 45 | Transfer rate: 1773.62 [Kbytes/sec] received 46 | 47 | Connection Times (ms) 48 | min mean[+/-sd] median max 49 | Connect: 0 0 0.8 0 10 50 | Processing: 33 51 14.8 50 186 51 | Waiting: 33 51 14.8 50 186 52 | Total: 33 51 15.2 50 191 53 | 54 | Percentage of the requests served within a certain time (ms) 55 | 50% 50 56 | 66% 55 57 | 75% 58 58 | 80% 60 59 | 90% 66 60 | 95% 80 61 | 98% 92 62 | 99% 115 63 | 100% 191 (longest request) 64 | ``` 65 | 66 | #### Apache 100 / 10 000 67 | ``` 68 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections_simpler/apache.php 69 | 70 | [...] 71 | 72 | Server Software: Apache/2.4.25 73 | Server Hostname: 192.168.0.233 74 | Server Port: 8083 75 | 76 | Document Path: /swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections_simpler/apache.php 77 | Document Length: 792 bytes 78 | 79 | Concurrency Level: 100 80 | Time taken for tests: 8.374 seconds 81 | Complete requests: 10000 82 | Failed requests: 0 83 | Write errors: 0 84 | Keep-Alive requests: 9967 85 | Total transferred: 10448069 bytes 86 | HTML transferred: 7920000 bytes 87 | Requests per second: 1194.24 [#/sec] (mean) 88 | Time per request: 83.735 [ms] (mean) 89 | Time per request: 0.837 [ms] (mean, across all concurrent requests) 90 | Transfer rate: 1218.50 [Kbytes/sec] received 91 | 92 | Connection Times (ms) 93 | min mean[+/-sd] median max 94 | Connect: 0 0 1.6 0 20 95 | Processing: 37 83 18.3 81 296 96 | Waiting: 37 83 18.2 81 296 97 | Total: 37 83 19.0 81 296 98 | 99 | Percentage of the requests served within a certain time (ms) 100 | 50% 81 101 | 66% 86 102 | 75% 91 103 | 80% 94 104 | 90% 104 105 | 95% 113 106 | 98% 129 107 | 99% 156 108 | 100% 296 (longest request) 109 | ``` 110 | 111 | #### Swoole 500 / 10 00 112 | ``` 113 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8082/ 114 | 115 | [...] 116 | 117 | Server Software: swoole-http-server 118 | Server Hostname: 192.168.0.233 119 | Server Port: 8082 120 | 121 | Document Path: / 122 | Document Length: 792 bytes 123 | 124 | Concurrency Level: 500 125 | Time taken for tests: 5.482 seconds 126 | Complete requests: 10000 127 | Failed requests: 0 128 | Write errors: 0 129 | Keep-Alive requests: 10000 130 | Total transferred: 9460000 bytes 131 | HTML transferred: 7920000 bytes 132 | Requests per second: 1824.30 [#/sec] (mean) 133 | Time per request: 274.077 [ms] (mean) 134 | Time per request: 0.548 [ms] (mean, across all concurrent requests) 135 | Transfer rate: 1685.34 [Kbytes/sec] received 136 | 137 | Connection Times (ms) 138 | min mean[+/-sd] median max 139 | Connect: 0 2 8.7 0 55 140 | Processing: 97 262 39.6 251 462 141 | Waiting: 47 262 39.7 251 462 142 | Total: 102 264 39.0 251 498 143 | 144 | Percentage of the requests served within a certain time (ms) 145 | 50% 251 146 | 66% 261 147 | 75% 273 148 | 80% 290 149 | 90% 318 150 | 95% 341 151 | 98% 378 152 | 99% 401 153 | 100% 498 (longest request) 154 | ``` 155 | 156 | #### Apache 500 / 10 000 157 | ``` 158 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections_simpler/apache.php 159 | 160 | [...] 161 | 162 | Server Software: Apache/2.4.25 163 | Server Hostname: 192.168.0.233 164 | Server Port: 8083 165 | 166 | Document Path: /swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections_simpler/apache.php 167 | Document Length: 792 bytes 168 | 169 | Concurrency Level: 500 170 | Time taken for tests: 13.827 seconds 171 | Complete requests: 10000 172 | Failed requests: 244 173 | (Connect: 0, Receive: 0, Length: 244, Exceptions: 0) 174 | Write errors: 0 175 | Keep-Alive requests: 9756 176 | Total transferred: 10195276 bytes 177 | HTML transferred: 7726752 bytes 178 | Requests per second: 723.21 [#/sec] (mean) 179 | Time per request: 691.361 [ms] (mean) 180 | Time per request: 1.383 [ms] (mean, across all concurrent requests) 181 | Transfer rate: 720.05 [Kbytes/sec] received 182 | 183 | Connection Times (ms) 184 | min mean[+/-sd] median max 185 | Connect: 0 1 5.7 0 61 186 | Processing: 38 343 1142.3 122 8368 187 | Waiting: 38 227 872.3 122 8368 188 | Total: 38 344 1145.0 122 8428 189 | 190 | Percentage of the requests served within a certain time (ms) 191 | 50% 122 192 | 66% 133 193 | 75% 141 194 | 80% 148 195 | 90% 177 196 | 95% 347 197 | 98% 5006 198 | 99% 8241 199 | 100% 8428 (longest request) 200 | ``` 201 | 202 | #### Swoole 1 000 / 10 000 203 | ``` 204 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8082/ 205 | 206 | [...] 207 | 208 | Server Software: swoole-http-server 209 | Server Hostname: 192.168.0.233 210 | Server Port: 8082 211 | 212 | Document Path: / 213 | Document Length: 792 bytes 214 | 215 | Concurrency Level: 1000 216 | Time taken for tests: 5.111 seconds 217 | Complete requests: 10000 218 | Failed requests: 0 219 | Write errors: 0 220 | Keep-Alive requests: 10000 221 | Total transferred: 9460000 bytes 222 | HTML transferred: 7920000 bytes 223 | Requests per second: 1956.75 [#/sec] (mean) 224 | Time per request: 511.052 [ms] (mean) 225 | Time per request: 0.511 [ms] (mean, across all concurrent requests) 226 | Transfer rate: 1807.70 [Kbytes/sec] received 227 | 228 | Connection Times (ms) 229 | min mean[+/-sd] median max 230 | Connect: 0 7 21.6 0 106 231 | Processing: 35 472 93.1 453 1041 232 | Waiting: 35 472 93.1 453 1041 233 | Total: 43 479 95.8 454 1135 234 | 235 | Percentage of the requests served within a certain time (ms) 236 | 50% 454 237 | 66% 467 238 | 75% 478 239 | 80% 491 240 | 90% 587 241 | 95% 685 242 | 98% 803 243 | 99% 861 244 | 100% 1135 (longest request) 245 | ``` 246 | #### Apache 1 000 / 10 000 247 | ``` 248 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections_simpler/apache.php 249 | 250 | [...] 251 | 252 | Server Software: Apache/2.4.25 253 | Server Hostname: 192.168.0.233 254 | Server Port: 8083 255 | 256 | Document Path: /swoole_tests/swoole-performance-tests/real_app_simulation_with_files_and_connections_simpler/apache.php 257 | Document Length: 792 bytes 258 | 259 | Concurrency Level: 1000 260 | Time taken for tests: 14.238 seconds 261 | Complete requests: 10000 262 | Failed requests: 256 263 | (Connect: 0, Receive: 0, Length: 256, Exceptions: 0) 264 | Write errors: 0 265 | Keep-Alive requests: 9744 266 | Total transferred: 10182838 bytes 267 | HTML transferred: 7717248 bytes 268 | Requests per second: 702.33 [#/sec] (mean) 269 | Time per request: 1423.829 [ms] (mean) 270 | Time per request: 1.424 [ms] (mean, across all concurrent requests) 271 | Transfer rate: 698.41 [Kbytes/sec] received 272 | 273 | Connection Times (ms) 274 | min mean[+/-sd] median max 275 | Connect: 0 5 91.0 0 3008 276 | Processing: 38 496 1569.3 220 14080 277 | Waiting: 38 373 1388.9 219 14080 278 | Total: 38 502 1596.0 220 14174 279 | 280 | Percentage of the requests served within a certain time (ms) 281 | 50% 220 282 | 66% 232 283 | 75% 240 284 | 80% 246 285 | 90% 286 286 | 95% 404 287 | 98% 5005 288 | 99% 13981 289 | 100% 14174 (longest request) 290 | ``` -------------------------------------------------------------------------------- /real_app_simulation_with_files_and_connections_simpler/apache.php: -------------------------------------------------------------------------------- 1 | connect_error) 22 | { 23 | die("$mysqli->connect_errno: $mysqli->connect_error"); 24 | } 25 | 26 | $stmt = $mysqli->prepare("SELECT * FROM test1"); 27 | $stmt->execute(); 28 | $result = $stmt->get_result(); 29 | $data = []; 30 | while($row = $result->fetch_assoc()) { 31 | $data[] = $row; 32 | } 33 | 34 | apcu_add('test1_data', $data); 35 | } 36 | } 37 | 38 | //write some files 39 | $file_content = 'some content here'; 40 | for( $aa = 0; $aa < 1; $aa++) { 41 | $file_name = './files/apache'.$aa.'.txt'; 42 | file_put_contents($file_name, $file_content); 43 | } 44 | 45 | //read some files 46 | for( $aa = 0; $aa < 1; $aa++) { 47 | $file_name = './files/apache'.$aa.'.txt'; 48 | $file_content = file_get_contents($file_name); 49 | } 50 | 51 | //do some db reads 52 | $mysqli = new mysqli("p:".MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB); 53 | for( $aa = 0; $aa < 3; $aa++) { 54 | $stmt = $mysqli->prepare("SELECT SLEEP(0.01)");//simulate a time consuming query 55 | $stmt->execute(); 56 | $result = $stmt->get_result(); 57 | $sql_data = []; 58 | while($row = $result->fetch_assoc()) { 59 | $sql_data[] = $row; 60 | } 61 | } 62 | 63 | print_r($data); 64 | 65 | 66 | -------------------------------------------------------------------------------- /real_app_simulation_with_files_and_connections_simpler/swoole.php: -------------------------------------------------------------------------------- 1 | available_connections)) { 25 | $this->initialize_connections($connection_class); 26 | } 27 | 28 | $Connection = $this->available_connections[$connection_class]->pop();//blocks and waits until one is available if there are no available ones 29 | 30 | return $Connection; 31 | } 32 | 33 | public function free_connection(ConnectionInterface $Connection) : void 34 | { 35 | $connection_class = get_class($Connection); 36 | 37 | $this->available_connections[$connection_class]->push($Connection); 38 | } 39 | 40 | private function initialize_connections(string $connection_class) : void 41 | { 42 | $this->available_connections[$connection_class] = new \Swoole\Coroutine\Channel(self::MAX_CONNECTIONS); 43 | for ($aa = 0; $aa < self::MAX_CONNECTIONS ; $aa++) { 44 | $Connection = new $connection_class(); 45 | $this->available_connections[$connection_class]->push($Connection); 46 | } 47 | } 48 | 49 | } 50 | 51 | interface ConnectionInterface 52 | { 53 | } 54 | 55 | class MysqlConnection implements ConnectionInterface 56 | { 57 | 58 | private const CONNECTION_SETTINGS = [ 59 | 'host' => MYSQL_HOST, 60 | 'port' => MYSQL_PORT, 61 | 'user' => MYSQL_USER, 62 | 'password' => MYSQL_PASS, 63 | 'database' => MYSQL_DB, 64 | ]; 65 | 66 | private $SwooleMysql; 67 | 68 | public function __construct() 69 | { 70 | $this->SwooleMysql = new Swoole\Coroutine\MySQL(); 71 | $this->SwooleMysql->connect(self::CONNECTION_SETTINGS); 72 | } 73 | 74 | public function __call(string $method, array $args) 75 | { 76 | return call_user_func_array([$this->SwooleMysql, $method], $args); 77 | } 78 | 79 | public function __get(string $property) 80 | { 81 | return $this->SwooleMysql->{$property}; 82 | } 83 | 84 | } 85 | 86 | 87 | $http = new Swoole\Http\Server('0.0.0.0', 8082, SWOOLE_PROCESS); 88 | $http->set(['worker_num' => swoole_cpu_num() * 2]); 89 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 90 | 91 | static $cache = []; 92 | 93 | static $Pool; 94 | if ($Pool === NULL) { 95 | $Pool = new Pool; 96 | } 97 | 98 | //loop through many cached objects 99 | for ($aa = 0 ; $aa < 1000; $aa++) { 100 | if (empty($cache['test1_data'])) { 101 | $Connection = $Pool->get_connection(MysqlConnection::class); 102 | 103 | $stmt = $Connection->prepare("SELECT * FROM test1"); 104 | if ($stmt === FALSE) { 105 | print $Connection->connect_error; 106 | print $Connection->error; 107 | } 108 | $cache['test1_data'] = $stmt->execute(); 109 | $Pool->free_connection($Connection); 110 | } 111 | $data = $cache['test1_data']; 112 | } 113 | 114 | //write some files 115 | $file_content = 'some content here'; 116 | for( $aa = 0; $aa < 1; $aa++) { 117 | $file_name = './files/swoole_'.$aa.'.txt'; 118 | Swoole\Coroutine\System::writeFile($file_name, $file_content); 119 | } 120 | 121 | //read some files 122 | for( $aa = 0; $aa < 1; $aa++) { 123 | $file_name = './files/swoole_'.$aa.'.txt'; 124 | $file_content = Swoole\Coroutine\System::readFile($file_name); 125 | } 126 | 127 | //do some DB reads 128 | $Connection = $Pool->get_connection(MysqlConnection::class); 129 | for ($aa = 0; $aa < 3; $aa++) { 130 | $stmt = $Connection->prepare("SELECT SLEEP(0.01)");//simulate a time consuming query 131 | $sql_data = $stmt->execute(); 132 | } 133 | $Pool->free_connection($Connection); 134 | 135 | 136 | $str = print_r($data, TRUE); 137 | 138 | 139 | $response->end($str); 140 | }); 141 | $http->start(); -------------------------------------------------------------------------------- /results/combined_chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenashkov/swoole-performance-tests/868c23e8578eeab8c5e3a29db5d80d2da44cdcf1/results/combined_chart.png -------------------------------------------------------------------------------- /results/graph_requests_100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenashkov/swoole-performance-tests/868c23e8578eeab8c5e3a29db5d80d2da44cdcf1/results/graph_requests_100.png -------------------------------------------------------------------------------- /results/graph_requests_1000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenashkov/swoole-performance-tests/868c23e8578eeab8c5e3a29db5d80d2da44cdcf1/results/graph_requests_1000.png -------------------------------------------------------------------------------- /results/graph_requests_500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenashkov/swoole-performance-tests/868c23e8578eeab8c5e3a29db5d80d2da44cdcf1/results/graph_requests_500.png -------------------------------------------------------------------------------- /results/results.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenashkov/swoole-performance-tests/868c23e8578eeab8c5e3a29db5d80d2da44cdcf1/results/results.ods -------------------------------------------------------------------------------- /results/results_requests_100.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenashkov/swoole-performance-tests/868c23e8578eeab8c5e3a29db5d80d2da44cdcf1/results/results_requests_100.ods -------------------------------------------------------------------------------- /results/results_requests_1000.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenashkov/swoole-performance-tests/868c23e8578eeab8c5e3a29db5d80d2da44cdcf1/results/results_requests_1000.ods -------------------------------------------------------------------------------- /results/results_requests_500.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenashkov/swoole-performance-tests/868c23e8578eeab8c5e3a29db5d80d2da44cdcf1/results/results_requests_500.ods -------------------------------------------------------------------------------- /simple_real_app_simulation/README.md: -------------------------------------------------------------------------------- 1 | # Simple real application simulation test 2 | 3 | This test represents what a Swoole application/microservice should aim to be - use extensive caching, and very little and fast IO operations. 4 | The amount of loaded classes does not affects the performance. 5 | This test does 1000 reads from cache, loads 100 classes and performs 2 fast DB queries. 6 | 7 | The results are: 8 | - Swoole 100 / 10 000 - Requests per second: **2288.58** 9 | - Apache/mod_php 100 / 10 000 - Requests per second: **1250.36** 10 | - Swoole 500 / 10 000 - Requests per second: **2011.11** 11 | - Apache/mod_php 500 / 10 000 - Requests per second: **774.52** with **196 failed requests** 12 | - Swoole 1 000 / 10 000 - Requests per second: **2228.23** 13 | - Apache/mod_php 1 000 / 10 000 - Requests per second: **failed with 7702 completed requests** 14 | 15 | 16 | #### Swoole 100 / 10 000 17 | ``` 18 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8082/ 19 | 20 | [...] 21 | 22 | Server Software: swoole-http-server 23 | Server Hostname: 192.168.0.233 24 | Server Port: 8082 25 | 26 | Document Path: / 27 | Document Length: 792 bytes 28 | 29 | Concurrency Level: 100 30 | Time taken for tests: 4.370 seconds 31 | Complete requests: 10000 32 | Failed requests: 0 33 | Write errors: 0 34 | Keep-Alive requests: 10000 35 | Total transferred: 9460000 bytes 36 | HTML transferred: 7920000 bytes 37 | Requests per second: 2288.58 [#/sec] (mean) 38 | Time per request: 43.695 [ms] (mean) 39 | Time per request: 0.437 [ms] (mean, across all concurrent requests) 40 | Transfer rate: 2114.25 [Kbytes/sec] received 41 | 42 | Connection Times (ms) 43 | min mean[+/-sd] median max 44 | Connect: 0 0 0.9 0 12 45 | Processing: 2 43 12.8 44 172 46 | Waiting: 2 43 12.8 43 172 47 | Total: 2 43 13.1 44 178 48 | 49 | Percentage of the requests served within a certain time (ms) 50 | 50% 44 51 | 66% 47 52 | 75% 49 53 | 80% 51 54 | 90% 61 55 | 95% 64 56 | 98% 69 57 | 99% 84 58 | 100% 178 (longest request) 59 | ``` 60 | #### Apache 100 / 10 000 61 | ``` 62 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 100 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/simple_real_app_simulation/apache.php 63 | 64 | [...] 65 | 66 | Server Software: Apache/2.4.25 67 | Server Hostname: 192.168.0.233 68 | Server Port: 8083 69 | 70 | Document Path: /swoole_tests/swoole-performance-tests/simple_real_app_simulation/apache.php 71 | Document Length: 792 bytes 72 | 73 | Concurrency Level: 100 74 | Time taken for tests: 7.998 seconds 75 | Complete requests: 10000 76 | Failed requests: 0 77 | Write errors: 0 78 | Keep-Alive requests: 9961 79 | Total transferred: 10447964 bytes 80 | HTML transferred: 7920000 bytes 81 | Requests per second: 1250.36 [#/sec] (mean) 82 | Time per request: 79.977 [ms] (mean) 83 | Time per request: 0.800 [ms] (mean, across all concurrent requests) 84 | Transfer rate: 1275.76 [Kbytes/sec] received 85 | 86 | Connection Times (ms) 87 | min mean[+/-sd] median max 88 | Connect: 0 0 1.6 0 22 89 | Processing: 9 79 37.9 75 405 90 | Waiting: 9 79 37.9 75 405 91 | Total: 9 79 38.1 75 405 92 | 93 | Percentage of the requests served within a certain time (ms) 94 | 50% 75 95 | 66% 85 96 | 75% 94 97 | 80% 101 98 | 90% 124 99 | 95% 146 100 | 98% 180 101 | 99% 208 102 | 100% 405 (longest request) 103 | ``` 104 | #### Swoole 500 / 10 000 105 | ``` 106 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8082/ 107 | 108 | [...] 109 | 110 | Server Software: swoole-http-server 111 | Server Hostname: 192.168.0.233 112 | Server Port: 8082 113 | 114 | Document Path: / 115 | Document Length: 792 bytes 116 | 117 | Concurrency Level: 500 118 | Time taken for tests: 4.972 seconds 119 | Complete requests: 10000 120 | Failed requests: 0 121 | Write errors: 0 122 | Keep-Alive requests: 10000 123 | Total transferred: 9460000 bytes 124 | HTML transferred: 7920000 bytes 125 | Requests per second: 2011.11 [#/sec] (mean) 126 | Time per request: 248.619 [ms] (mean) 127 | Time per request: 0.497 [ms] (mean, across all concurrent requests) 128 | Transfer rate: 1857.92 [Kbytes/sec] received 129 | 130 | Connection Times (ms) 131 | min mean[+/-sd] median max 132 | Connect: 0 2 8.5 0 48 133 | Processing: 3 240 200.1 225 1672 134 | Waiting: 3 240 200.1 225 1672 135 | Total: 3 242 206.1 225 1719 136 | 137 | Percentage of the requests served within a certain time (ms) 138 | 50% 225 139 | 66% 232 140 | 75% 236 141 | 80% 240 142 | 90% 251 143 | 95% 267 144 | 98% 1287 145 | 99% 1337 146 | 100% 1719 (longest request) 147 | ``` 148 | #### Aapche 500 / 10 000 149 | ``` 150 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 500 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/simple_real_app_simulation/apache.php 151 | 152 | [...] 153 | 154 | Server Software: Apache/2.4.25 155 | Server Hostname: 192.168.0.233 156 | Server Port: 8083 157 | 158 | Document Path: /swoole_tests/swoole-performance-tests/simple_real_app_simulation/apache.php 159 | Document Length: 792 bytes 160 | 161 | Concurrency Level: 500 162 | Time taken for tests: 12.911 seconds 163 | Complete requests: 10000 164 | Failed requests: 196 165 | (Connect: 0, Receive: 0, Length: 196, Exceptions: 0) 166 | Write errors: 0 167 | Keep-Alive requests: 9805 168 | Total transferred: 10246530 bytes 169 | HTML transferred: 7765560 bytes 170 | Requests per second: 774.52 [#/sec] (mean) 171 | Time per request: 645.565 [ms] (mean) 172 | Time per request: 1.291 [ms] (mean, across all concurrent requests) 173 | Transfer rate: 775.01 [Kbytes/sec] received 174 | 175 | Connection Times (ms) 176 | min mean[+/-sd] median max 177 | Connect: 0 1 15.7 0 1001 178 | Processing: 10 362 1364.2 100 12775 179 | Waiting: 10 268 1196.9 100 12775 180 | Total: 10 364 1370.0 100 12826 181 | 182 | Percentage of the requests served within a certain time (ms) 183 | 50% 100 184 | 66% 123 185 | 75% 142 186 | 80% 158 187 | 90% 217 188 | 95% 333 189 | 98% 5005 190 | 99% 7427 191 | 100% 12826 (longest request) 192 | ``` 193 | 194 | #### Swoole 1 000 / 10 000 195 | ``` 196 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8082/ 197 | 198 | [...] 199 | 200 | Server Software: swoole-http-server 201 | Server Hostname: 192.168.0.233 202 | Server Port: 8082 203 | 204 | Document Path: / 205 | Document Length: 792 bytes 206 | 207 | Concurrency Level: 1000 208 | Time taken for tests: 4.488 seconds 209 | Complete requests: 10000 210 | Failed requests: 0 211 | Write errors: 0 212 | Keep-Alive requests: 10000 213 | Total transferred: 9460000 bytes 214 | HTML transferred: 7920000 bytes 215 | Requests per second: 2228.23 [#/sec] (mean) 216 | Time per request: 448.786 [ms] (mean) 217 | Time per request: 0.449 [ms] (mean, across all concurrent requests) 218 | Transfer rate: 2058.51 [Kbytes/sec] received 219 | 220 | Connection Times (ms) 221 | min mean[+/-sd] median max 222 | Connect: 0 7 21.3 0 102 223 | Processing: 74 418 62.9 418 638 224 | Waiting: 3 418 62.9 418 638 225 | Total: 105 425 56.2 420 678 226 | 227 | Percentage of the requests served within a certain time (ms) 228 | 50% 420 229 | 66% 431 230 | 75% 439 231 | 80% 449 232 | 90% 472 233 | 95% 530 234 | 98% 601 235 | 99% 616 236 | 100% 678 (longest request) 237 | ``` 238 | #### Apache 1 000 / 10 000 239 | ``` 240 | root@vesko-dev /home/local/swoole_tests/swoole-performance-tests (master) # ab -c 1000 -n 10000 -k http://192.168.0.233:8083/swoole_tests/swoole-performance-tests/simple_real_app_simulation/apache.php 241 | This is ApacheBench, Version 2.3 <$Revision: 1430300 $> 242 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 243 | Licensed to The Apache Software Foundation, http://www.apache.org/ 244 | 245 | Benchmarking 192.168.0.233 (be patient) 246 | Completed 1000 requests 247 | Completed 2000 requests 248 | Completed 3000 requests 249 | Completed 4000 requests 250 | Completed 5000 requests 251 | Completed 6000 requests 252 | Completed 7000 requests 253 | apr_socket_recv: Connection reset by peer (104) 254 | Total of 7702 requests completed 255 | ``` 256 | 257 | -------------------------------------------------------------------------------- /simple_real_app_simulation/apache.php: -------------------------------------------------------------------------------- 1 | connect_error) 18 | { 19 | die("$mysqli->connect_errno: $mysqli->connect_error"); 20 | } 21 | 22 | $stmt = $mysqli->prepare("SELECT * FROM test1"); 23 | $stmt->execute(); 24 | $result = $stmt->get_result(); 25 | $data = []; 26 | while($row = $result->fetch_assoc()) { 27 | $data[] = $row; 28 | } 29 | 30 | apcu_add('test1_data', $data); 31 | } 32 | } 33 | 34 | //do some db reads 35 | $mysqli = new mysqli("p:".MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB); 36 | for( $aa = 0; $aa < 2; $aa++) { 37 | $stmt = $mysqli->prepare("SELECT * FROM test1");//simple query 38 | $stmt->execute(); 39 | $result = $stmt->get_result(); 40 | $sql_data = []; 41 | while($row = $result->fetch_assoc()) { 42 | $sql_data[] = $row; 43 | } 44 | } 45 | 46 | print_r($data); 47 | 48 | 49 | -------------------------------------------------------------------------------- /simple_real_app_simulation/swoole.php: -------------------------------------------------------------------------------- 1 | available_connections)) { 21 | $this->initialize_connections($connection_class); 22 | } 23 | 24 | $Connection = $this->available_connections[$connection_class]->pop();//blocks and waits until one is available if there are no available ones 25 | 26 | return $Connection; 27 | } 28 | 29 | public function free_connection(ConnectionInterface $Connection) : void 30 | { 31 | $connection_class = get_class($Connection); 32 | 33 | $this->available_connections[$connection_class]->push($Connection); 34 | } 35 | 36 | private function initialize_connections(string $connection_class) : void 37 | { 38 | $this->available_connections[$connection_class] = new \Swoole\Coroutine\Channel(self::MAX_CONNECTIONS); 39 | for ($aa = 0; $aa < self::MAX_CONNECTIONS ; $aa++) { 40 | $Connection = new $connection_class(); 41 | $this->available_connections[$connection_class]->push($Connection); 42 | } 43 | } 44 | 45 | } 46 | 47 | interface ConnectionInterface 48 | { 49 | } 50 | 51 | class MysqlConnection implements ConnectionInterface 52 | { 53 | 54 | private const CONNECTION_SETTINGS = [ 55 | 'host' => MYSQL_HOST, 56 | 'port' => MYSQL_PORT, 57 | 'user' => MYSQL_USER, 58 | 'password' => MYSQL_PASS, 59 | 'database' => MYSQL_DB, 60 | ]; 61 | 62 | private $SwooleMysql; 63 | 64 | public function __construct() 65 | { 66 | $this->SwooleMysql = new Swoole\Coroutine\MySQL(); 67 | $this->SwooleMysql->connect(self::CONNECTION_SETTINGS); 68 | } 69 | 70 | public function __call(string $method, array $args) 71 | { 72 | return call_user_func_array([$this->SwooleMysql, $method], $args); 73 | } 74 | 75 | public function __get(string $property) 76 | { 77 | return $this->SwooleMysql->{$property}; 78 | } 79 | 80 | } 81 | 82 | 83 | $http = new Swoole\Http\Server('0.0.0.0', 8082, SWOOLE_PROCESS); 84 | $http->set(['worker_num' => swoole_cpu_num() * 2]); 85 | $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { 86 | 87 | static $cache = []; 88 | 89 | static $Pool; 90 | if ($Pool === NULL) { 91 | $Pool = new Pool; 92 | } 93 | 94 | //loop through many cached objects 95 | for ($aa = 0 ; $aa < 1000; $aa++) { 96 | if (empty($cache['test1_data'])) { 97 | $Connection = $Pool->get_connection(MysqlConnection::class); 98 | 99 | $stmt = $Connection->prepare("SELECT * FROM test1"); 100 | if ($stmt === FALSE) { 101 | print $Connection->connect_error; 102 | print $Connection->error; 103 | } 104 | $cache['test1_data'] = $stmt->execute(); 105 | $Pool->free_connection($Connection); 106 | } 107 | $data = $cache['test1_data']; 108 | } 109 | 110 | //do some DB reads 111 | $Connection = $Pool->get_connection(MysqlConnection::class); 112 | for ($aa = 0; $aa < 2; $aa++) { 113 | $stmt = $Connection->prepare("SELECT * FROM test1");//simple query 114 | $sql_data = $stmt->execute(); 115 | } 116 | $Pool->free_connection($Connection); 117 | 118 | 119 | $str = print_r($data, TRUE); 120 | 121 | 122 | $response->end($str); 123 | }); 124 | $http->start(); -------------------------------------------------------------------------------- /test_db_dump.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 4.4.15.10 3 | -- https://www.phpmyadmin.net 4 | -- 5 | -- Host: localhost 6 | -- Generation Time: Oct 31, 2019 at 03:28 PM 7 | -- Server version: 5.5.64-MariaDB 8 | -- PHP Version: 5.4.16 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | SET time_zone = "+00:00"; 12 | 13 | -- 14 | -- Database: `swoole_tests` 15 | -- 16 | 17 | -- -------------------------------------------------------- 18 | 19 | -- 20 | -- Table structure for table `test1` 21 | -- 22 | 23 | CREATE TABLE IF NOT EXISTS `test1` ( 24 | `test1_id` int(10) unsigned NOT NULL, 25 | `test1_timestamp` int(10) unsigned NOT NULL, 26 | `test1_data` varchar(2000) NOT NULL, 27 | `test1_some_fk` int(10) unsigned NOT NULL 28 | ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; 29 | 30 | -- 31 | -- Dumping data for table `test1` 32 | -- 33 | 34 | INSERT INTO `test1` (`test1_id`, `test1_timestamp`, `test1_data`, `test1_some_fk`) VALUES 35 | (1, 1572448636, '1RmUhmZyDJdrDCJQoDjI\r\ndE6ufBmMVEsHTWj1NJON\r\nZFgwVFaoYhfgdfha6XLd\r\nzzmOCfIpOvkHp51WTgAC\r\nS8G75rs9R1f0STvvqEJV\r\nLxTiBh5erPbekjeWIqeI\r\nRD2Qtsco7oxkCZHwiedW\r\nd1m2NQBEgXGYmsElg3rp\r\nzIpqKTiOv4DhiocH8sKB\r\nPqJKzGBH5MAJEcxR2cJC', 33), 36 | (2, 1572448639, 'j7gcSP6ieqcRYgRFHw8H\r\nxngh61mwtkUg93tGm3Uk\r\ncmTNMV3QlJ2fFGpFGl39\r\n1HWEWQPBgQZL1tkqjpUr\r\n1rpHa996rZUgSsebcNSR\r\n5gQ2qfdaMYe7u8MmkduS\r\nS0dyi20nPKBaRDjBk1As\r\nGqyLyL6RwInHNoucj6wB\r\nTz5M6yIC1oosLXs8Qaoh\r\nDSaRYmht1bE3hrPd1m4h', 35); 37 | 38 | -- 39 | -- Indexes for dumped tables 40 | -- 41 | 42 | -- 43 | -- Indexes for table `test1` 44 | -- 45 | ALTER TABLE `test1` 46 | ADD PRIMARY KEY (`test1_id`); 47 | 48 | -- 49 | -- AUTO_INCREMENT for dumped tables 50 | -- 51 | 52 | -- 53 | -- AUTO_INCREMENT for table `test1` 54 | -- 55 | ALTER TABLE `test1` 56 | MODIFY `test1_id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3; -------------------------------------------------------------------------------- /zend_framework/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "zendframework/zendframework": "^3.0" 4 | } 5 | } 6 | --------------------------------------------------------------------------------