├── .gitignore ├── .gitmodules ├── Application ├── DbConnectException.php ├── DbQueryException.php ├── DependencyException.php └── TestApplication.php ├── LICENSE ├── README.md ├── Tests ├── AlterIndexes.php ├── ArrayKeyVsIsset.php ├── ArraySearchVsInArray.php ├── ArrayVsObject.php ├── Autoloaders.php ├── CloneVsNew.php ├── CompareISO8601Dates.php ├── Crc32VsMd5.php ├── CtypeDigitVsRegex.php ├── CtypeSymbolsVsPregMatch.php ├── CurlOptimizations.php ├── DbGeneratorTest.php ├── DoubleVsSingleQuotes.php ├── DynamicVsStaticClass.php ├── EmptyArrayCheck.php ├── ExtractIdFromMultiDimArr.php ├── FastestIncrement.php ├── FileExistsVsStreamResolve.php ├── FixedWidthFieldsParsing.php ├── ForVsRange.php ├── ForeachValueReferences.php ├── ForeachVsArrayDiff.php ├── ForeachVsWhile.php ├── FwriteVsFilePutContents.php ├── GeoDistance.php ├── GetClassName.php ├── GetFirstArrayElement.php ├── HashBench.php ├── IfOptimization.php ├── IfVsAnd.php ├── IncludeFunctionInForeach.php ├── IncludeOnceVsRequireOnce.php ├── IncludeVsRequire.php ├── IntvalVsTypeCast.php ├── IsAVsInstanceOf.php ├── JsonVsSerialize.php ├── JsonVsSerializeInt.php ├── ListVsSubstr.php ├── MagicVsDefinitionGet.php ├── MagicVsDefinitionSet.php ├── MysqlVsMysqliVsPdoRead.php ├── MysqlVsMysqliVsPdoWrite.php ├── PdoEmulatedPlaceholders.php ├── PharAutoLoad.php ├── PharMultiCall.php ├── RandVsMtRand.php ├── RecursiveArrayIteratorPerformance.php ├── RecursiveDirectoryScan.php ├── RegexNamedSubPatterns.php ├── RemoveSpaceFromString.php ├── ReturnArrayVsObject.php ├── RoundToNearestThousand.php ├── SelfVsClass.php ├── SplFixedArrayVsArrayAdd.php ├── SplFixedArrayVsArrayCreate.php ├── SplFixedArrayVsArrayGet.php ├── StrRepeatFillPerformance.php ├── StringGenBench.php ├── StrposVsStrstr.php ├── StrtrVsStrReplace.php ├── ThisVsSelf.php ├── Translite.php └── UniqueNumbers.php ├── lib ├── DataBase │ ├── Adapters │ │ ├── DbAdapterBase.php │ │ ├── PdoAdapter.php │ │ └── iDbAdapter.php │ ├── ConnectionPools │ │ └── ConnectionPool.php │ ├── Connections │ │ ├── DbConnection.php │ │ └── PdoConnection.php │ ├── Db.php │ ├── DbBase.php │ ├── DbFilter.php │ ├── DbPaginator.php │ ├── DbTransactionHandler.php │ ├── Exceptions │ │ └── DbException.php │ └── Loggers │ │ └── PdoErrorLogger.php ├── NotPhar │ ├── ClassEight.php │ ├── ClassFive.php │ ├── ClassFour.php │ ├── ClassNine.php │ ├── ClassOne.php │ ├── ClassSeven.php │ ├── ClassSix.php │ ├── ClassTen.php │ ├── ClassThree.php │ └── ClassTwo.php └── archive.phar ├── screen.png ├── test-example ├── test-list └── test-new /.gitignore: -------------------------------------------------------------------------------- 1 | test 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/Veles"] 2 | path = lib/Veles 3 | url = ../Veles.git 4 | -------------------------------------------------------------------------------- /Application/DbConnectException.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Чтв Ноя 21 17:50:52 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Application; 16 | 17 | use Veles\Tools\CliColor; 18 | 19 | /** 20 | * Class DbConnectException 21 | * 22 | * @author Yancharuk Alexander 23 | */ 24 | class DbConnectException extends \Exception 25 | { 26 | /** 27 | * Prints custom connection error message 28 | * 29 | * @param string $msg Error message 30 | */ 31 | final public function __construct($msg) 32 | { 33 | $warning = new CliColor('red', ['bold']); 34 | $str = "Database connection error!\n$msg\n"; 35 | echo $warning->setString($str); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Application/DbQueryException.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Чтв Ноя 21 18:05:22 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Application; 16 | 17 | use Veles\Tools\CliColor; 18 | 19 | /** 20 | * Class DbQueryException 21 | * 22 | * @author Yancharuk Alexander 23 | */ 24 | class DbQueryException extends \Exception 25 | { 26 | /** 27 | * Prints custom database query error message 28 | * 29 | * @param string $msg Error message 30 | */ 31 | final public function __construct($msg) 32 | { 33 | $warning = new CliColor('red', ['bold']); 34 | $str = "Database query error!\n$msg\n"; 35 | echo $warning->setString($str); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Application/DependencyException.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Чтв Ноя 21 15:28:44 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Application; 16 | 17 | use Veles\Tools\CliColor; 18 | 19 | /** 20 | * Class DependencyException 21 | * 22 | * @author Yancharuk Alexander 23 | */ 24 | class DependencyException extends \Exception 25 | { 26 | /** 27 | * Prints warning about unresolved dependencies 28 | * 29 | * @param string $class_names Unresolved classes and extensions names 30 | */ 31 | final public function __construct($class_names) 32 | { 33 | $warning = new CliColor('red', ['bold']); 34 | $str = "WARNING!\nFound unresolved dependencies:\n\n"; 35 | echo $warning->setString($str); 36 | 37 | $dependencies = new CliColor('white', ['bold']); 38 | echo $dependencies->setString("$class_names\n"); 39 | 40 | $warning->setStyle(['default']); 41 | $str = "Please, install proper extensions for test completion.\n"; 42 | echo $warning->setString($str); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Application/TestApplication.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Сбт Фев 16 17:01:16 2013 11 | * @license The BSD 3-Clause License. 12 | * 13 | */ 14 | 15 | namespace Application; 16 | 17 | use Veles\Application\Application; 18 | use Veles\Tools\CliColor; 19 | 20 | /** 21 | * Class TestApplication 22 | * 23 | * @author Yancharuk Alexander 24 | */ 25 | class TestApplication extends Application 26 | { 27 | /** @var array Results array */ 28 | private $results = []; 29 | /** @var array Class names of dependencies */ 30 | protected $class_dependencies = []; 31 | /** @var array Extension dependencies */ 32 | protected $ext_dependencies = []; 33 | /** @var int Test repeats */ 34 | protected $repeats = 10000; 35 | /** @var string Result output format */ 36 | protected $result_format = "%-16s%-16s%-16s%-16s\n"; 37 | 38 | /** 39 | * @param int $repeats 40 | */ 41 | public function setRepeats($repeats) 42 | { 43 | $this->repeats = $repeats; 44 | } 45 | 46 | /** 47 | * @return int 48 | */ 49 | public function getRepeats() 50 | { 51 | return $this->repeats; 52 | } 53 | 54 | /** 55 | * @param array $results 56 | */ 57 | public function setResults($results) 58 | { 59 | $this->results = $results; 60 | } 61 | 62 | /** 63 | * @return array 64 | */ 65 | public function getResults() 66 | { 67 | return $this->results; 68 | } 69 | 70 | /** 71 | * Test dependencies 72 | */ 73 | public function testDependencies() 74 | { 75 | $errors = ''; 76 | foreach ($this->class_dependencies as $class_name) { 77 | if (class_exists($class_name)) continue; 78 | $errors .= sprintf( 79 | "%-12s%-20s%-10s\n", 'Class ', $class_name, ' not found!' 80 | ); 81 | } 82 | 83 | foreach ($this->ext_dependencies as $ext_name) { 84 | if (extension_loaded($ext_name)) continue; 85 | $errors .= sprintf( 86 | "%-12s%-20s%-10s\n", 'Extension ', $ext_name, ' not loaded!' 87 | ); 88 | } 89 | 90 | if ('' !== $errors) { 91 | throw new DependencyException($errors); 92 | } 93 | } 94 | 95 | /** 96 | * Display results 97 | */ 98 | public function showResults() 99 | { 100 | $results = $this->getResults(); 101 | asort($results); 102 | $best = key($results); 103 | $string = new CliColor; 104 | 105 | printf( 106 | $this->result_format, 107 | 'Test name', 'Repeats', 'Result', 'Performance' 108 | ); 109 | 110 | foreach ($results as $name => $value) { 111 | list($percent, $color) = $this->getPercentDiff( 112 | $results[$best], $value 113 | ); 114 | 115 | $value = number_format($value, 6); 116 | $string->setColor($color); 117 | $string->setString($value); 118 | 119 | printf( 120 | $this->getFixedFormat(), 121 | $name, $this->getRepeats(), $string . ' sec', $percent . '%' 122 | ); 123 | } 124 | } 125 | 126 | /** 127 | * Printf format cant correctly align shell-colored string, so 128 | * fix this by adding additional spaces 129 | */ 130 | private function getFixedFormat() 131 | { 132 | $regexp = '/^%-\d+s%-\d+s%-(\d+)s%-\d+s\n$/'; 133 | $match_result = preg_match($regexp, $this->result_format, $matches); 134 | $position = (1 === $match_result) ? $matches[1] + 11 : 16; 135 | 136 | return preg_replace('/^(%-\d+s%-\d+s%-)(\d+)(s%-\d+s\n)$/', 137 | '${1}' . $position . '$3', $this->result_format 138 | ); 139 | } 140 | 141 | /** 142 | * Calculate result percent difference 143 | * 144 | * @param int $best float Best test result 145 | * @param int $current float Result for comparison 146 | * 147 | * @return array [CliColor, string] 148 | */ 149 | private function getPercentDiff($best, $current) 150 | { 151 | $diff = $current - $best; 152 | $percent = $best / 100; 153 | $value = $diff / $percent; 154 | $result = new CliColor; 155 | 156 | if ($value > 0 and $value <= 10) { 157 | $color = 'yellow'; 158 | $value = number_format($value, 2); 159 | $string = "-$value"; 160 | } elseif ($value > 10) { 161 | $color = 'red'; 162 | $value = number_format($value, 2); 163 | $string = "-$value"; 164 | } else { 165 | $color = 'green'; 166 | $value = number_format($value, 2); 167 | $string = "+$value"; 168 | } 169 | 170 | $result->setColor($color); 171 | $result->setstring($string); 172 | 173 | return [$result, $color]; 174 | } 175 | 176 | /** 177 | * Add result for further displaying 178 | * 179 | * @param string $name 180 | * @param float $value 181 | */ 182 | public function addResult($name, $value) 183 | { 184 | if ($value < 0.000001) $value = 0.000001; 185 | 186 | $this->results[$name] = $value; 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2025, Alexander Yancharuk 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | Neither the name of the {organization} nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub license][License img]][License src] [![Conventional Commits][Conventional commits badge]][Conventional commits src] 2 | 3 | php-bench 4 | ========= 5 | **Console tools for benchmark PHP algorithms.** 6 | 7 | ![Alt php-bench](https://github.com/nafigator/php-bench/raw/master/screen.png) 8 | 9 | ### Requirements: 10 | 11 | * PHP CLI 5.4+ 12 | 13 | ### Installation: 14 | 15 | ```bash 16 | git clone https://github.com/nafigator/php-bench.git 17 | cd php-bench 18 | git submodule update --init 19 | ``` 20 | 21 | ### Usage: 22 | 23 | Create copy of test executable and modify your local settings: 24 | 25 | ```text 26 | cp test-example test 27 | ``` 28 | 29 | 30 | Show available tests: 31 | 32 | ```text 33 | ./test-list 34 | ``` 35 | 36 | Create test skeleton: 37 | 38 | ```text 39 | ./test-new [] 40 | ``` 41 | **Test name** - name of new test class.
42 | **Block count** - how much test blocks generate 43 | 44 | Run test: 45 | 46 | ```text 47 | ./test 48 | ``` 49 | 50 | 51 | **Class** - class name from Tests directory. 52 | 53 | ### Examples: 54 | 55 | ```text 56 | ./test CloneVsNew 57 | ./test IncludeVsRequire 58 | ``` 59 | 60 | 61 | ### Run all tests: 62 | 63 | ```bash 64 | for name in $(find Tests -type f -name '*.php' | sed 's/^Tests\/\(.*\)\.php/\1/'); 65 | do echo;echo $name;echo; ./test $name; 66 | done; 67 | ``` 68 | 69 | *** 70 | If you'd like to see other PHP-algorithm comparison in this collection, feel 71 | free to create a new issue. Thanks! 72 | 73 | [License img]: https://img.shields.io/github/license/nafigator/php-bench?color=teal 74 | [License src]: https://tldrlegal.com/license/bsd-3-clause-license-(revised) 75 | [Conventional commits src]: https://conventionalcommits.org 76 | [Conventional commits badge]: https://img.shields.io/badge/Conventional%20Commits-1.0.0-teal.svg 77 | -------------------------------------------------------------------------------- /Tests/AlterIndexes.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2018 Yancharuk Alexander 11 | * @date Tue Jul 31 11:19:56 2018 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use PDO; 19 | use Veles\DataBase\Db; 20 | use Veles\Tools\CliProgressBar; 21 | use Veles\Tools\Timer; 22 | use Application\TestApplication; 23 | 24 | /** 25 | * Class AlterIndexes 26 | * 27 | * @author Yancharuk Alexander 28 | */ 29 | class AlterIndexes extends TestApplication 30 | { 31 | protected $repeats = 10000; 32 | protected $sql = " 33 | INSERT united_requests (country_id, affiliate_id, created_date, created_datetime, status, phone, email, incoming_data, error_code, error_message) 34 | VALUES (7, 24234, now(), now(), 1, '7965444333222', 'mail@mail.ru', '', 0, '') 35 | "; 36 | 37 | public function run() 38 | { 39 | $repeats = $this->getRepeats(); 40 | $this->prepareDataBase(); 41 | 42 | Timer::reset(); 43 | $bar = new CliProgressBar($repeats); 44 | for ($i = 1; $i <= $repeats; ++$i) { 45 | Timer::start(); 46 | Db::query($this->sql); 47 | Timer::stop(); 48 | $bar->update($i); 49 | } 50 | 51 | $this->addResult('insert', Timer::get()); 52 | 53 | // Отправляем выполнение процесса в бэкграунд 54 | shell_exec("mysql landings -e 'alter table united_requests drop key wmid_date;alter table united_requests add key wmid_date (created_date, country_id, affiliate_id);' 2>sql.log >sql.log &"); 55 | printf("Key rebuild started\n"); 56 | 57 | Timer::reset(); 58 | $bar = new CliProgressBar($repeats); 59 | for ($i = 1; $i <= $repeats; ++$i) { 60 | Timer::start(); 61 | Db::query($this->sql); 62 | Timer::stop(); 63 | $bar->update($i); 64 | } 65 | 66 | $this->addResult('insert + key', Timer::get()); 67 | } 68 | 69 | protected function prepareDataBase() 70 | { 71 | // $dbh = new PDO("mysql:host=localhost", 'root', ''); 72 | // $dbh->exec("CREATE DATABASE IF NOT EXISTS landings"); 73 | // 74 | // $dbh->exec(" 75 | // CREATE TABLE IF NOT EXISTS `united_countries` ( 76 | // `id` int(11) NOT NULL AUTO_INCREMENT, 77 | // `name` varchar(255) NOT NULL, 78 | // `code` varchar(255) NOT NULL, 79 | // `description` text, 80 | // PRIMARY KEY (`id`) 81 | // ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8"); 82 | // 83 | // $dbh->exec(" 84 | // INSERT INTO `united_countries` VALUES 85 | // (7,'Россия','RU',NULL), 86 | // (6,'Украина лидовая','UA_lead',NULL), 87 | // (5,'Испания','ES',NULL), 88 | // (4,'Польша','PL',NULL), 89 | // (3,'Казахстан','KZ',NULL), 90 | // (2,'Единая Россия под авто','',NULL), 91 | // (1,'Украина','UA',NULL) 92 | // "); 93 | // 94 | // $dbh->exec(" 95 | // CREATE TABLE IF NOT EXISTS `united_requests` ( 96 | // `id` int(11) NOT NULL AUTO_INCREMENT, 97 | // `country_id` int(11) NOT NULL, 98 | // `affiliate_id` int(10) unsigned NOT NULL, 99 | // `created_date` date NOT NULL, 100 | // `created_datetime` datetime NOT NULL, 101 | // `status` tinyint(4) NOT NULL, 102 | // `phone` varchar(32) DEFAULT NULL, 103 | // `email` varchar(255) DEFAULT NULL, 104 | // `incoming_data` text NOT NULL, 105 | // `error_code` int(4) DEFAULT NULL, 106 | // `error_message` varchar(1024) DEFAULT NULL, 107 | // `ip` varchar(40) DEFAULT NULL, 108 | // PRIMARY KEY (`id`), 109 | // KEY `phone_index` (`phone`), 110 | // KEY `date` (`created_date`), 111 | // KEY `countries` (`country_id`), 112 | // KEY `phone_date` (`phone`,`created_date`), 113 | // KEY `wmid_date` (`created_date`,`country_id`,`affiliate_id`), 114 | // CONSTRAINT `country_fk` FOREIGN KEY (`country_id`) REFERENCES `united_countries` (`id`) 115 | // ) ENGINE=InnoDB AUTO_INCREMENT=153958338 DEFAULT CHARSET=utf8"); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /Tests/ArrayKeyVsIsset.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Tue Sep 24 17:34:28 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class ArrayKeyVsIsset 23 | * @author Yancharuk Alexander 24 | */ 25 | class ArrayKeyVsIsset extends TestApplication 26 | { 27 | protected $repeats = 10000; 28 | protected $result_format = "%-20s%-16s%-16s%-16s\n"; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | $array = ['prop' => 'value']; 34 | 35 | $bar = new CliProgressBar($repeats); 36 | for ($i = 1; $i <= $repeats; ++$i) { 37 | Timer::start(); 38 | array_key_exists('prop', $array); 39 | Timer::stop(); 40 | $bar->update($i); 41 | } 42 | 43 | $this->addResult('array_key_exists', Timer::get()); 44 | 45 | $bar = new CliProgressBar($repeats); 46 | 47 | Timer::reset(); 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | Timer::start(); 50 | isset($array['prop']); 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('isset', Timer::get()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Tests/ArraySearchVsInArray.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Tue Dec 31 17:30:46 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class ArraySearchVsInArray 23 | * 24 | * @author Alexander Yancharuk 25 | */ 26 | class ArraySearchVsInArray extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $haystack = [ 33 | 'apple', 34 | 'banana', 35 | 'cherry', 36 | 'potato', 37 | 'rutabaga' 38 | ]; 39 | $needle = 'rutabaga'; 40 | 41 | $repeats = $this->getRepeats(); 42 | 43 | $bar = new CliProgressBar($repeats); 44 | for ($i = 1; $i <= $repeats; ++$i) { 45 | Timer::start(); 46 | array_search($needle, $haystack); 47 | Timer::stop(); 48 | $bar->update($i); 49 | } 50 | 51 | $this->addResult('array_search', Timer::get()); 52 | 53 | Timer::reset(); 54 | $bar = new CliProgressBar($repeats); 55 | for ($i = 1; $i <= $repeats; ++$i) { 56 | Timer::start(); 57 | in_array($needle, $haystack); 58 | Timer::stop(); 59 | $bar->update($i); 60 | } 61 | 62 | $this->addResult('in_array', Timer::get()); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Tests/ArrayVsObject.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Tue Sep 24 17:03:53 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class ArrayVsObject 23 | * @author Yancharuk Alexander 24 | */ 25 | class ArrayVsObject extends TestApplication 26 | { 27 | protected $repeats = 1000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | $element_count = 50; 33 | 34 | $bar = new CliProgressBar($repeats); 35 | for ($i = 1; $i <= $repeats; ++$i) { 36 | Timer::start(); 37 | $object = new \stdClass(); 38 | Timer::stop(); 39 | for ($j = 0; $j <= $element_count; ++$j) { 40 | Timer::start(); 41 | $object->{$j} = true; 42 | Timer::stop(); 43 | } 44 | $bar->update($i); 45 | } 46 | 47 | unset($object); 48 | $this->addResult('$object', Timer::get()); 49 | $bar = new CliProgressBar($repeats); 50 | 51 | Timer::reset(); 52 | for ($i = 1; $i <= $repeats; ++$i) { 53 | Timer::start(); 54 | $array = []; 55 | Timer::stop(); 56 | for ($j = 0; $j <= $element_count; ++$j) { 57 | Timer::start(); 58 | $array[$j] = true; 59 | Timer::stop(); 60 | } 61 | $bar->update($i); 62 | } 63 | 64 | $this->addResult('$array', Timer::get()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Tests/Autoloaders.php: -------------------------------------------------------------------------------- 1 | 13 | * @date Tue May 19 05:59:24 2015 14 | * @license The BSD 3-Clause License 15 | * 16 | */ 17 | 18 | namespace Tests; 19 | 20 | use Veles\Tools\CliProgressBar; 21 | use Veles\Tools\Timer; 22 | use Application\TestApplication; 23 | 24 | /** 25 | * Class Autoloaders 26 | * 27 | * @author Alexander Yancharuk 28 | */ 29 | class AutoLoaders extends TestApplication 30 | { 31 | const NS_SEPARATOR = '\\'; 32 | const PREFIX_SEPARATOR = '_'; 33 | const LOAD_NS = 'namespaces'; 34 | const LOAD_PREFIX = 'prefixes'; 35 | const ACT_AS_FALLBACK = 'fallback_autoloader'; 36 | const AUTOREGISTER_ZF = 'autoregister_zf'; 37 | 38 | protected static $fallbackAutoloaderFlag = false; 39 | protected static $namespaces = array('\Veles' => '\Veles'); 40 | 41 | protected $repeats = 10000; 42 | 43 | public function run() 44 | { 45 | $repeats = $this->getRepeats(); 46 | 47 | $class = '\Veles\Config'; 48 | 49 | $bar = new CliProgressBar($repeats); 50 | for ($i = 1; $i <= $repeats; ++$i) { 51 | Timer::start(); 52 | $isFallback = self::ZendisFallbackAutoloader(); 53 | if (false !== strpos($class, self::NS_SEPARATOR)) { 54 | if (self::ZendloadClass($class, self::LOAD_NS)) { 55 | //return $class; 56 | } elseif ($isFallback) { 57 | self::ZendloadClass($class, self::ACT_AS_FALLBACK); 58 | } 59 | //return false; 60 | } 61 | if (false !== strpos($class, self::PREFIX_SEPARATOR)) { 62 | if (self::ZendloadClass($class, self::LOAD_PREFIX)) { 63 | //return $class; 64 | } elseif ($isFallback) { 65 | self::ZendloadClass($class, self::ACT_AS_FALLBACK); 66 | } 67 | //return false; 68 | } 69 | if ($isFallback) { 70 | self::ZendloadClass($class, self::ACT_AS_FALLBACK); 71 | } 72 | Timer::stop(); 73 | $bar->update($i); 74 | } 75 | 76 | $this->addResult('Zend', Timer::get()); 77 | 78 | Timer::reset(); 79 | $bar = new CliProgressBar($repeats); 80 | for ($i = 1; $i <= $repeats; ++$i) { 81 | Timer::start(); 82 | $file = preg_replace('/\\\|_(?!.+\\\)/', DIRECTORY_SEPARATOR, $class) . '.php'; 83 | if (false !== ($full_path = stream_resolve_include_path($file))) 84 | /** @noinspection PhpIncludeInspection */ 85 | //require $full_path; 86 | Timer::stop(); 87 | $bar->update($i); 88 | } 89 | 90 | $this->addResult('Veles', Timer::get()); 91 | } 92 | 93 | public static function ZendisFallbackAutoloader() 94 | { 95 | return self::$fallbackAutoloaderFlag; 96 | } 97 | 98 | public static function ZendloadClass($class, $type) 99 | { 100 | if (!in_array($type, array(self::LOAD_NS, self::LOAD_PREFIX, self::ACT_AS_FALLBACK))) { 101 | require_once __DIR__ . '/Exception/InvalidArgumentException.php'; 102 | throw new Exception\InvalidArgumentException(); 103 | } 104 | // Fallback autoloading 105 | if ($type === self::ACT_AS_FALLBACK) { 106 | // create filename 107 | $filename = self::ZendtransformClassNameToFilename($class, ''); 108 | $resolvedName = stream_resolve_include_path($filename); 109 | if ($resolvedName !== false) { 110 | return true; 111 | } 112 | return false; 113 | } 114 | // Namespace and/or prefix autoloading 115 | foreach (self::$$type as $leader => $path) { 116 | if (0 === strpos($class, $leader)) { 117 | // Trim off leader (namespace or prefix) 118 | $trimmedClass = substr($class, strlen($leader)); 119 | // create filename 120 | $filename = self::ZendtransformClassNameToFilename($trimmedClass, $path); 121 | if (file_exists($filename)) { 122 | //return include $filename; 123 | } 124 | } 125 | } 126 | return false; 127 | } 128 | 129 | public static function ZendtransformClassNameToFilename($class, $directory) 130 | { 131 | // $class may contain a namespace portion, in which case we need 132 | // to preserve any underscores in that portion. 133 | $matches = array(); 134 | preg_match('/(?P.+\\\)?(?P[^\\\]+$)/', $class, $matches); 135 | $class = (isset($matches['class'])) ? $matches['class'] : ''; 136 | $namespace = (isset($matches['namespace'])) ? $matches['namespace'] : ''; 137 | return $directory 138 | . str_replace(self::NS_SEPARATOR, '/', $namespace) 139 | . str_replace(self::PREFIX_SEPARATOR, '/', $class) 140 | . '.php'; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Tests/CloneVsNew.php: -------------------------------------------------------------------------------- 1 | 10 | * @date 2013-08-04 10:16 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class CloneVsNew 23 | * @author Yancharuk Alexander 24 | */ 25 | class CloneVsNew extends TestApplication 26 | { 27 | protected $repeats = 1000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | 33 | $bar = new CliProgressBar($repeats); 34 | for ($i = 1; $i <= $repeats; ++$i) { 35 | Timer::start(); 36 | $myobj1 = new \stdClass(); 37 | $myobj2 = new \stdClass(); 38 | $myobj3 = new \stdClass(); 39 | $myobj4 = new \stdClass(); 40 | Timer::stop(); 41 | $bar->update($i); 42 | } 43 | 44 | $this->addResult('New', Timer::get()); 45 | 46 | $bar = new CliProgressBar($repeats); 47 | 48 | Timer::reset(); 49 | for ($i = 1; $i <= $repeats; ++$i) { 50 | Timer::start(); 51 | $myobj1 = new \stdClass(); 52 | $myobj2 = clone $myobj1; 53 | $myobj3 = clone $myobj1; 54 | $myobj4 = clone $myobj1; 55 | Timer::stop(); 56 | $bar->update($i); 57 | } 58 | 59 | $this->addResult('Clone', Timer::get()); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Tests/CompareISO8601Dates.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Sun Dec 29 12:18:22 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class CompareISO8601Dates 23 | * 24 | * @author Alexander Yancharuk 25 | */ 26 | class CompareISO8601Dates extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | $date1 = '2011-09-09'; 34 | $date2 = '2011-09-08'; 35 | 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | if (strtotime($date1) > strtotime($date2)) {} 40 | Timer::stop(); 41 | $bar->update($i); 42 | } 43 | 44 | $this->addResult('strtotime', Timer::get()); 45 | 46 | Timer::reset(); 47 | $bar = new CliProgressBar($repeats); 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | Timer::start(); 50 | if (strcmp($date1, $date2) > 0) {} 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('strcmp', Timer::get()); 56 | 57 | Timer::reset(); 58 | $bar = new CliProgressBar($repeats); 59 | for ($i = 1; $i <= $repeats; ++$i) { 60 | Timer::start(); 61 | if (new \DateTime($date1) > new \DateTime($date2)) {} 62 | Timer::stop(); 63 | $bar->update($i); 64 | } 65 | 66 | $this->addResult('DateTime', Timer::get()); 67 | 68 | Timer::reset(); 69 | $bar = new CliProgressBar($repeats); 70 | for ($i = 1; $i <= $repeats; ++$i) { 71 | Timer::start(); 72 | if ($date1 > $date2) {} 73 | Timer::stop(); 74 | $bar->update($i); 75 | } 76 | 77 | $this->addResult('string', Timer::get()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Tests/Crc32VsMd5.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Сбт Фев 16 17:01:16 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class Crc32VsMd5 23 | * @author Yancharuk Alexander 24 | */ 25 | class Crc32VsMd5 extends TestApplication 26 | { 27 | const TEST = 'simple value'; 28 | protected $repeats = 1000; 29 | 30 | public function run() 31 | { 32 | $string = 'some random data'; 33 | 34 | $repeats = $this->getRepeats(); 35 | $bar = new CliProgressBar($repeats); 36 | for ($i = 1; $i <= $repeats; ++$i) { 37 | Timer::start(); 38 | dechex(crc32($string)); 39 | Timer::stop(); 40 | $bar->update($i); 41 | } 42 | 43 | $this->addResult('dechex(crc32())', Timer::get()); 44 | 45 | $bar = new CliProgressBar($repeats); 46 | Timer::reset(); 47 | for ($i = 1; $i <= $repeats; ++$i) { 48 | Timer::start(); 49 | hash('crc32b', $string); 50 | Timer::stop(); 51 | $bar->update($i); 52 | } 53 | 54 | $this->addResult('hash(\'crc32b\')', Timer::get()); 55 | 56 | $bar = new CliProgressBar($repeats); 57 | Timer::reset(); 58 | for ($i = 1; $i <= $repeats; ++$i) { 59 | Timer::start(); 60 | md5($string); 61 | Timer::stop(); 62 | $bar->update($i); 63 | } 64 | 65 | $this->addResult('md5()', Timer::get()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Tests/CtypeDigitVsRegex.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Fri Jun 21 18:28:00 2019 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class CtypeDigitVsRegex 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class CtypeDigitVsRegex extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | $string = '123412341243'; 35 | 36 | Timer::reset(); 37 | $bar = new CliProgressBar($repeats); 38 | for ($i = 1; $i <= $repeats; ++$i) { 39 | Timer::start(); 40 | ctype_digit($string); 41 | Timer::stop(); 42 | $bar->update($i); 43 | } 44 | 45 | $this->addResult('ctype_digit', Timer::get()); 46 | 47 | Timer::reset(); 48 | $bar = new CliProgressBar($repeats); 49 | for ($i = 1; $i <= $repeats; ++$i) { 50 | Timer::start(); 51 | preg_match('/^\d+$/', $string); 52 | Timer::stop(); 53 | $bar->update($i); 54 | } 55 | 56 | $this->addResult('preg_match', Timer::get()); 57 | 58 | Timer::reset(); 59 | $bar = new CliProgressBar($repeats); 60 | for ($i = 1; $i <= $repeats; ++$i) { 61 | Timer::start(); 62 | filter_var($string, FILTER_VALIDATE_INT); 63 | Timer::stop(); 64 | $bar->update($i); 65 | } 66 | 67 | $this->addResult('filter_var', Timer::get()); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Tests/CtypeSymbolsVsPregMatch.php: -------------------------------------------------------------------------------- 1 | 4 | * @file CtypeSymbolsVsPregMatch.php 5 | * 6 | * PHP version 5.6+ 7 | * 8 | * @author Yancharuk Alexander 9 | * @copyright © 2013-2021 Yancharuk Alexander 10 | * @date Fri Jun 21 18:35:59 2019 11 | * @license The BSD 3-Clause License. 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Veles\Tools\CliProgressBar; 18 | use Veles\Tools\Timer; 19 | use Application\TestApplication; 20 | 21 | /** 22 | * Class CtypeSymbolsVsPregMatch 23 | * 24 | * @author Yancharuk Alexander 25 | */ 26 | class CtypeSymbolsVsPregMatch extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | $string = 'sdfsdfULKJlkj'; 34 | 35 | Timer::reset(); 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | ctype_alpha($string); 40 | Timer::stop(); 41 | $bar->update($i); 42 | } 43 | 44 | $this->addResult('ctype', Timer::get()); 45 | 46 | Timer::reset(); 47 | $bar = new CliProgressBar($repeats); 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | Timer::start(); 50 | preg_match('/^[A-Za-z]+$/', $string); 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('preg_match', Timer::get()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Tests/CurlOptimizations.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright © 2013-2021 Yancharuk Alexander 13 | * @date Tue Apr 23 10:34:20 2019 14 | * @license The BSD 3-Clause License. 15 | * 16 | */ 17 | 18 | namespace Tests; 19 | 20 | use Veles\Tools\CliProgressBar; 21 | use Veles\Tools\Timer; 22 | use Application\TestApplication; 23 | 24 | /** 25 | * Class CurlOptimizations 26 | * 27 | * @author Yancharuk Alexander 28 | */ 29 | class CurlOptimizations extends TestApplication 30 | { 31 | protected $ext_dependencies = ['curl']; 32 | 33 | protected $repeats = 50; 34 | 35 | public function run() 36 | { 37 | $repeats = $this->getRepeats(); 38 | $curlHandler1 = curl_init('https://ya.ru'); 39 | 40 | curl_setopt_array($curlHandler1, [ 41 | CURLOPT_RETURNTRANSFER => true, 42 | ]); 43 | 44 | Timer::reset(); 45 | $bar = new CliProgressBar($repeats); 46 | for ($i = 1; $i <= $repeats; ++$i) { 47 | Timer::start(); 48 | curl_exec($curlHandler1); 49 | Timer::stop(); 50 | $bar->update($i); 51 | } 52 | 53 | $this->addResult('default', Timer::get()); 54 | curl_close($curlHandler1); 55 | 56 | $curlHandler2 = curl_init('https://ya.ru'); 57 | curl_setopt_array($curlHandler2, [ 58 | CURLOPT_RETURNTRANSFER => true, 59 | CURLOPT_ENCODING => '', 60 | CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, 61 | ]); 62 | 63 | Timer::reset(); 64 | $bar = new CliProgressBar($repeats); 65 | for ($i = 1; $i <= $repeats; ++$i) { 66 | Timer::start(); 67 | curl_exec($curlHandler2); 68 | Timer::stop(); 69 | $bar->update($i); 70 | } 71 | 72 | $this->addResult('optimized', Timer::get()); 73 | curl_close($curlHandler2); 74 | 75 | $curlHandler3 = curl_init('https://ya.ru'); 76 | curl_setopt_array($curlHandler3, [ 77 | CURLOPT_RETURNTRANSFER => true, 78 | CURLOPT_ENCODING => 'gzip', 79 | CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, 80 | CURLOPT_SSL_VERIFYHOST => false, 81 | CURLOPT_SSL_VERIFYPEER => false, 82 | ]); 83 | 84 | Timer::reset(); 85 | $bar = new CliProgressBar($repeats); 86 | for ($i = 1; $i <= $repeats; ++$i) { 87 | Timer::start(); 88 | curl_exec($curlHandler3); 89 | Timer::stop(); 90 | $bar->update($i); 91 | } 92 | 93 | $this->addResult('opt + no SSL', Timer::get()); 94 | curl_close($curlHandler3); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Tests/DbGeneratorTest.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright © 2013-2021 Yancharuk Alexander 12 | * @date Mon Dec 28 17:37:50 2015 13 | * @license The BSD 3-Clause License. 14 | * 15 | */ 16 | 17 | namespace Tests; 18 | 19 | use Application\DbConnectException; 20 | use Application\DbQueryException; 21 | use DataBase\Adapters\PdoAdapter; 22 | use DataBase\ConnectionPools\ConnectionPool; 23 | use DataBase\Connections\PdoConnection; 24 | use DataBase\Db; 25 | use mysqli; 26 | use PDO; 27 | use Veles\DataBase\Db as ODb; 28 | use Veles\Tools\CliProgressBar; 29 | use Veles\Tools\Timer; 30 | use Application\TestApplication; 31 | 32 | /** 33 | * Class DbGeneratorTest 34 | * 35 | * @author Yancharuk Alexander 36 | */ 37 | class DbGeneratorTest extends TestApplication 38 | { 39 | protected $class_dependencies = ['PDO', 'MySQLi']; 40 | protected $ext_dependencies = ['pdo_mysql', 'mysqli']; 41 | 42 | private $user = 'root'; 43 | private $host = 'localhost'; 44 | private $password = ''; 45 | private $database = 'php_bench_test'; 46 | 47 | protected $repeats = 1000; 48 | 49 | public function run() 50 | { 51 | $this->prepareTables(); 52 | $repeats = $this->getRepeats(); 53 | 54 | $sql = 'SELECT txt FROM test'; 55 | 56 | $bar = new CliProgressBar($repeats); 57 | for ($i = 1; $i <= $repeats; ++$i) { 58 | Timer::start(); 59 | $result = ODb::rows($sql); 60 | foreach ($result as $value) {} 61 | Timer::stop(); 62 | $bar->update($i); 63 | } 64 | 65 | $this->addResult('non-generator', Timer::get()); 66 | 67 | Timer::reset(); 68 | $bar = new CliProgressBar($repeats); 69 | 70 | // Db class initialization 71 | $pool = new ConnectionPool(); 72 | $conn = new PdoConnection('master'); 73 | 74 | $conn->setDsn("mysql:host=localhost;dbname=$this->database;charset=utf8") 75 | ->setUserName('root') 76 | ->setPassword('') 77 | ->setOptions([ 78 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 79 | PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 80 | PDO::ATTR_EMULATE_PREPARES => false 81 | ]); 82 | $pool->addConnection($conn, true); 83 | PdoAdapter::setPool($pool); 84 | Db::setAdapter(PdoAdapter::instance()); 85 | 86 | for ($i = 1; $i <= $repeats; ++$i) { 87 | Timer::start(); 88 | /** @var \Closure $result */ 89 | $result = Db::rows($sql); 90 | foreach ($result() as $value) {} 91 | Timer::stop(); 92 | $bar->update($i); 93 | } 94 | 95 | $this->addResult('generator', Timer::get()); 96 | 97 | $this->cleanup(); 98 | } 99 | 100 | /** 101 | * Prepares tables with data for test 102 | * 103 | * @throws \Application\DbQueryException 104 | * @throws \Application\DbConnectException 105 | */ 106 | public function prepareTables() 107 | { 108 | $mysqli = new mysqli($this->host, $this->user, $this->password); 109 | if ($mysqli->connect_errno) { 110 | throw new DbConnectException( 111 | "Connect Error ($mysqli->connect_errno)\n$mysqli->connect_error" 112 | ); 113 | } 114 | 115 | $mysqli->query('CREATE DATABASE IF NOT EXISTS ' . $this->database); 116 | if ($mysqli->errno) { 117 | throw new DbQueryException( 118 | "Query Error ($mysqli->errno)\n$mysqli->error" 119 | ); 120 | } 121 | 122 | $mysqli->select_db($this->database); 123 | $mysqli->query(" 124 | CREATE TABLE IF NOT EXISTS test ( 125 | id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 126 | txt CHAR(50) NOT NULL DEFAULT '' 127 | ) ENGINE INNODB 128 | "); 129 | if ($mysqli->errno) { 130 | throw new DbQueryException( 131 | "Query Error ($mysqli->errno)\n$mysqli->error" 132 | ); 133 | } 134 | 135 | $arr = []; 136 | $i = 0; 137 | while (++$i <= 5000) { 138 | $arr[] = uniqid('test-value::'); 139 | } 140 | 141 | $values = implode("'),('", $arr); 142 | $sql = "INSERT INTO test (txt) VALUES ('$values')"; 143 | $mysqli->query($sql); 144 | if ($mysqli->errno) { 145 | throw new DbQueryException( 146 | "Query Error ($mysqli->errno)\n$mysqli->error" 147 | ); 148 | } 149 | } 150 | 151 | /** 152 | * Cleanup database 153 | * 154 | * @throws \Application\DbQueryException 155 | * @throws \Application\DbConnectException 156 | */ 157 | public function cleanup() 158 | { 159 | $mysqli = new mysqli($this->host, $this->user, $this->password); 160 | if ($mysqli->connect_errno) { 161 | throw new DbConnectException( 162 | "Connect Error ($mysqli->connect_errno)\n$mysqli->connect_error" 163 | ); 164 | } 165 | 166 | $mysqli->query('DROP DATABASE ' . $this->database); 167 | if ($mysqli->errno) { 168 | throw new DbQueryException( 169 | "Query Error ($mysqli->errno)\n$mysqli->error" 170 | ); 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /Tests/DoubleVsSingleQuotes.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2018 Yancharuk Alexander 11 | * @date Tue Aug 07 19:05:30 2018 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class DoubleVsSingleQuotes 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class DoubleVsSingleQuotes extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | 35 | Timer::reset(); 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | $a = 'qwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdf'; 40 | Timer::stop(); 41 | $bar->update($i); 42 | } 43 | 44 | $this->addResult('Single', Timer::get()); 45 | 46 | Timer::reset(); 47 | $bar = new CliProgressBar($repeats); 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | Timer::start(); 50 | $a = "qwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdfqwertyasdf"; 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('Double', Timer::get()); 56 | } 57 | } -------------------------------------------------------------------------------- /Tests/DynamicVsStaticClass.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Tue Nov 10 13:17:44 2015 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class DynamicVsStaticClass 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class DynamicVsStaticClass extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | protected $result_format = "%-25s%-16s%-16s%-16s\n"; 31 | 32 | public function run() 33 | { 34 | $repeats = $this->getRepeats(); 35 | 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | $class = new DynamicClass; 40 | $class->testMethod(); 41 | Timer::stop(); 42 | $bar->update($i); 43 | } 44 | 45 | $this->addResult('Dynamic calls', Timer::get()); 46 | 47 | Timer::reset(); 48 | $bar = new CliProgressBar($repeats); 49 | for ($i = 1; $i <= $repeats; ++$i) { 50 | Timer::start(); 51 | (new DynamicClass)->testMethod(); 52 | Timer::stop(); 53 | $bar->update($i); 54 | } 55 | 56 | $this->addResult('Simple dynamic syntax', Timer::get()); 57 | 58 | Timer::reset(); 59 | $bar = new CliProgressBar($repeats); 60 | for ($i = 1; $i <= $repeats; ++$i) { 61 | Timer::start(); 62 | StaticClass::testMethod(); 63 | Timer::stop(); 64 | $bar->update($i); 65 | } 66 | 67 | $this->addResult('Static calls', Timer::get()); 68 | } 69 | } 70 | 71 | class DynamicClass 72 | { 73 | public function testMethod() {} 74 | } 75 | 76 | class StaticClass 77 | { 78 | public static function testMethod() {} 79 | } 80 | -------------------------------------------------------------------------------- /Tests/EmptyArrayCheck.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2018 Yancharuk Alexander 11 | * @date Wed Jun 06 16:51:07 2018 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class EmptyArrayCheck 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class EmptyArrayCheck extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | 35 | $array = [0]; 36 | 37 | Timer::reset(); 38 | $bar = new CliProgressBar($repeats); 39 | for ($i = 1; $i <= $repeats; ++$i) { 40 | Timer::start(); 41 | if (0 === count($array)); 42 | Timer::stop(); 43 | $bar->update($i); 44 | } 45 | 46 | $this->addResult('count', Timer::get()); 47 | 48 | Timer::reset(); 49 | $bar = new CliProgressBar($repeats); 50 | for ($i = 1; $i <= $repeats; ++$i) { 51 | Timer::start(); 52 | if (empty($array)); 53 | Timer::stop(); 54 | $bar->update($i); 55 | } 56 | 57 | $this->addResult('empty', Timer::get()); 58 | 59 | Timer::reset(); 60 | $bar = new CliProgressBar($repeats); 61 | for ($i = 1; $i <= $repeats; ++$i) { 62 | Timer::start(); 63 | if (!$array); 64 | Timer::stop(); 65 | $bar->update($i); 66 | } 67 | 68 | $this->addResult('bool', Timer::get()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Tests/ExtractIdFromMultiDimArr.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Сбт Фев 16 17:01:16 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class ExtractIdFromMultiDimArr 23 | * @author Yancharuk Alexander 24 | */ 25 | class ExtractIdFromMultiDimArr extends TestApplication 26 | { 27 | protected $repeats = 1000; 28 | 29 | public function run() 30 | { 31 | $array = [ 32 | ['ID' => '2'], 33 | ['ID' => '3'] 34 | ]; 35 | 36 | $repeats = $this->getRepeats(); 37 | $bar = new CliProgressBar($repeats); 38 | $result = []; 39 | for ($i = 1; $i <= $repeats; ++$i) { 40 | Timer::start(); 41 | $result = array_map(function($element) { 42 | return $element['ID']; 43 | }, $array); 44 | Timer::stop(); 45 | $bar->update($i); 46 | } 47 | 48 | $this->addResult('array_map', Timer::get()); 49 | 50 | $bar = new CliProgressBar($repeats); 51 | 52 | $result = []; 53 | Timer::reset(); 54 | for ($i = 1; $i <= $repeats; ++$i) { 55 | Timer::start(); 56 | foreach ($array as $element) { 57 | $result[] = $element['ID']; 58 | } 59 | Timer::stop(); 60 | $bar->update($i); 61 | } 62 | 63 | $this->addResult('foreach', Timer::get()); 64 | 65 | $bar = new CliProgressBar($repeats); 66 | 67 | $result = []; 68 | Timer::reset(); 69 | for ($i = 1; $i <= $repeats; ++$i) { 70 | Timer::start(); 71 | foreach ($array as $element) { 72 | array_push($result, $element['ID']); 73 | } 74 | Timer::stop(); 75 | $bar->update($i); 76 | } 77 | 78 | $this->addResult('array_push', Timer::get()); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Tests/FastestIncrement.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Fri Aug 14 18:02:18 2015 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Veles\Tools\CliProgressBar; 18 | use Veles\Tools\Timer; 19 | use Application\TestApplication; 20 | 21 | /** 22 | * Class FastestIncrement 23 | * 24 | * @author Yancharuk Alexander 25 | */ 26 | class FastestIncrement extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | 34 | $bar = new CliProgressBar($repeats); 35 | $x = 0; 36 | for ($i = 1; $i <= $repeats; ++$i) { 37 | Timer::start(); 38 | $x = $x + 1; 39 | Timer::stop(); 40 | $bar->update($i); 41 | } 42 | 43 | $this->addResult('$x = $x + 1', Timer::get()); 44 | 45 | Timer::reset(); 46 | $bar = new CliProgressBar($repeats); 47 | $x = 0; 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | Timer::start(); 50 | $x += 1; 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('$x += 1', Timer::get()); 56 | 57 | Timer::reset(); 58 | $bar = new CliProgressBar($repeats); 59 | $x = 0; 60 | for ($i = 1; $i <= $repeats; ++$i) { 61 | Timer::start(); 62 | $x++; 63 | Timer::stop(); 64 | $bar->update($i); 65 | } 66 | 67 | $this->addResult('$x++', Timer::get()); 68 | 69 | Timer::reset(); 70 | $bar = new CliProgressBar($repeats); 71 | $x = 0; 72 | for ($i = 1; $i <= $repeats; ++$i) { 73 | Timer::start(); 74 | ++$x; 75 | Timer::stop(); 76 | $bar->update($i); 77 | } 78 | 79 | $this->addResult('++$x', Timer::get()); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Tests/FileExistsVsStreamResolve.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Wed Jan 01 10:08:37 2014 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class FileExistsVsStreamResolve 23 | * 24 | * @author Alexander Yancharuk 25 | */ 26 | class FileExistsVsStreamResolve extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | $temp_file = tempnam(sys_get_temp_dir(), 'pb-prefix'); 34 | 35 | $bar = new CliProgressBar($repeats); 36 | for ($i = 1; $i <= $repeats; ++$i) { 37 | Timer::start(); 38 | file_exists($temp_file); 39 | Timer::stop(); 40 | $bar->update($i); 41 | } 42 | 43 | $this->addResult('file_exists', Timer::get()); 44 | 45 | Timer::reset(); 46 | $bar = new CliProgressBar($repeats); 47 | for ($i = 1; $i <= $repeats; ++$i) { 48 | Timer::start(); 49 | stream_resolve_include_path($temp_file); 50 | Timer::stop(); 51 | $bar->update($i); 52 | } 53 | 54 | $this->addResult('stream_resolve', Timer::get()); 55 | 56 | unlink($temp_file); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tests/FixedWidthFieldsParsing.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Wed Nov 22 13:11:27 2017 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class FixedWidthFieldsParsing 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class FixedWidthFieldsParsing extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $string = '01/01/2001Description 25 symbols 8.23 0'; 34 | $repeats = $this->getRepeats(); 35 | 36 | Timer::reset(); 37 | $bar = new CliProgressBar($repeats); 38 | for ($i = 1; $i <= $repeats; ++$i) { 39 | Timer::start(); 40 | $matches = unpack('A10date/A25desc/A10price/A*flag', $string); 41 | Timer::stop(); 42 | $bar->update($i); 43 | } 44 | 45 | $this->addResult('unpack()', Timer::get()); 46 | 47 | Timer::reset(); 48 | $bar = new CliProgressBar($repeats); 49 | for ($i = 1; $i <= $repeats; ++$i) { 50 | Timer::start(); 51 | preg_match('/(?[\d\/]{10})(?.{25})(?[\d\. ]{10})(?0|1)/', $string, $matches); 52 | Timer::stop(); 53 | $bar->update($i); 54 | } 55 | 56 | $this->addResult('preg_match()', Timer::get()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tests/ForVsRange.php: -------------------------------------------------------------------------------- 1 | 10 | * @date 2013-08-24 14:33 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class ForVsRange 23 | * @author Yancharuk Alexander 24 | */ 25 | class ForVsRange extends TestApplication 26 | { 27 | protected $repeats = 10000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | 33 | $tmp = 100; 34 | $bar = new CliProgressBar($repeats); 35 | for ($i = 1; $i <= $repeats; ++$i) { 36 | Timer::start(); 37 | for ($j = 0; $j <= $tmp; ++$j) {} 38 | Timer::stop(); 39 | $bar->update($i); 40 | } 41 | 42 | $this->addResult('for', Timer::get()); 43 | 44 | $bar = new CliProgressBar($repeats); 45 | 46 | Timer::reset(); 47 | for ($i = 1; $i <= $repeats; ++$i) { 48 | Timer::start(); 49 | foreach (range(0, $tmp) as $j) {} 50 | Timer::stop(); 51 | $bar->update($i); 52 | } 53 | 54 | $this->addResult('while & range', Timer::get()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Tests/ForeachValueReferences.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Mon Jun 20 18:40:39 2016 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class ForeachValueReferences 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class ForeachValueReferences extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | 35 | $numeric_array = range(0, 1000); 36 | 37 | $bar = new CliProgressBar($repeats); 38 | for ($i = 1; $i <= $repeats; ++$i) { 39 | Timer::start(); 40 | foreach ($numeric_array as $key => &$value) {} 41 | Timer::stop(); 42 | $bar->update($i); 43 | } 44 | 45 | $this->addResult('references', Timer::get()); 46 | 47 | Timer::reset(); 48 | $bar = new CliProgressBar($repeats); 49 | for ($i = 1; $i <= $repeats; ++$i) { 50 | Timer::start(); 51 | foreach ($numeric_array as $key => $value) {} 52 | Timer::stop(); 53 | $bar->update($i); 54 | } 55 | 56 | $this->addResult('variables', Timer::get()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tests/ForeachVsArrayDiff.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Tue Dec 10 10:42:28 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class ForeachVsArrayDiff 23 | * 24 | * @author Alexander Yancharuk 25 | */ 26 | class ForeachVsArrayDiff extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | $max = 1000; 34 | $min = 0; 35 | 36 | $a1 = $a2 = range($min, $max); 37 | $b1 = $b2 = []; 38 | $i = $min - 1; 39 | while(++$i <= $max) { 40 | $b1[$i] = $b2[$i] = mt_rand($min, $max); 41 | } 42 | 43 | $bar = new CliProgressBar($repeats); 44 | for ($i = 1; $i <= $repeats; ++$i) { 45 | Timer::start(); 46 | foreach ($b1 as $val) { 47 | unset($a1[$val]); 48 | } 49 | Timer::stop(); 50 | $bar->update($i); 51 | } 52 | 53 | $this->addResult('foreach', Timer::get()); 54 | 55 | Timer::reset(); 56 | $bar = new CliProgressBar($repeats); 57 | for ($i = 1; $i <= $repeats; ++$i) { 58 | Timer::start(); 59 | $a2 = array_diff_key($a2, array_flip($b2)); 60 | Timer::stop(); 61 | $bar->update($i); 62 | } 63 | 64 | $this->addResult('array_diff_key', Timer::get()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Tests/ForeachVsWhile.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Втр Сен 10 17:03:20 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class ForeachVsWhile 23 | * @author Yancharuk Alexander 24 | */ 25 | class ForeachVsWhile extends TestApplication 26 | { 27 | protected $repeats = 1000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | 33 | $bar = new CliProgressBar($repeats); 34 | for ($i = 1; $i <= $repeats; ++$i) { 35 | Timer::start(); 36 | $j = 0; while (++$j <= $repeats) {} 37 | Timer::stop(); 38 | $bar->update($i); 39 | } 40 | 41 | $this->addResult('while', Timer::get()); 42 | 43 | $bar = new CliProgressBar($repeats); 44 | 45 | Timer::reset(); 46 | for ($i = 1; $i <= $repeats; ++$i) { 47 | Timer::start(); 48 | for ($j = 0; $j < $repeats; ++$j) {} 49 | Timer::stop(); 50 | $bar->update($i); 51 | } 52 | 53 | $this->addResult('for', Timer::get()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Tests/FwriteVsFilePutContents.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Wed Aug 19 18:22:36 2015 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Veles\Tools\CliProgressBar; 18 | use Veles\Tools\Timer; 19 | use Application\TestApplication; 20 | 21 | /** 22 | * Class FwriteVsFilePutContents 23 | * 24 | * @author Yancharuk Alexander 25 | */ 26 | class FwriteVsFilePutContents extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | $filename1 = strtolower(uniqid('file')) . '.txt'; 34 | $filename2 = strtolower(uniqid('file')) . '.txt'; 35 | $string = genStrShuffle(100); 36 | 37 | $bar = new CliProgressBar($repeats); 38 | for ($i = 1; $i <= $repeats; ++$i) { 39 | Timer::start(); 40 | $file = fopen($filename1, 'a+'); 41 | flock($file, LOCK_EX); 42 | fwrite($file, $string); 43 | fclose($file); 44 | Timer::stop(); 45 | $bar->update($i); 46 | } 47 | 48 | $this->addResult('fwrite()', Timer::get()); 49 | 50 | Timer::reset(); 51 | $bar = new CliProgressBar($repeats); 52 | for ($i = 1; $i <= $repeats; ++$i) { 53 | Timer::start(); 54 | file_put_contents($filename2, $string, FILE_APPEND | LOCK_EX); 55 | Timer::stop(); 56 | $bar->update($i); 57 | } 58 | 59 | $this->addResult('put_contents()', Timer::get()); 60 | unlink($filename1); 61 | unlink($filename2); 62 | } 63 | } 64 | 65 | function genStrShuffle( 66 | $length = 22, 67 | $letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./' 68 | ) { 69 | return substr(str_shuffle(str_repeat($letters, 5)), 0, $length); 70 | } 71 | -------------------------------------------------------------------------------- /Tests/GeoDistance.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Fri Dec 02 10:46:02 2016 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class GeoDistance 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class GeoDistance extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | 35 | $latitude_from = 55.7402; 36 | $longitude_from = 37.5085; 37 | $latitude_to = 55.577206; 38 | $longitude_to = 38.914059; 39 | 40 | //var_dump(vincentyGreatCircleDistance($latitude_from, $longitude_from, $latitude_to, $longitude_to)); 41 | //var_dump(codexworldGetDistance($latitude_from, $longitude_from, $latitude_to, $longitude_to)); 42 | //var_dump(codexworldGetDistanceOpt($latitude_from, $longitude_from, $latitude_to, $longitude_to)); 43 | //var_dump(distanceUserChecker($latitude_from, $longitude_from, $latitude_to, $longitude_to)); 44 | //var_dump(distanceUserChecker1($latitude_from, $longitude_from, $latitude_to, $longitude_to)); 45 | //var_dump(distanceUserChecker2($latitude_from, $longitude_from, $latitude_to, $longitude_to)); 46 | 47 | Timer::reset(); 48 | $bar = new CliProgressBar($repeats); 49 | for ($i = 1; $i <= $repeats; ++$i) { 50 | Timer::start(); 51 | vincentyGreatCircleDistance($latitude_from, $longitude_from, $latitude_to, $longitude_to); 52 | Timer::stop(); 53 | $bar->update($i); 54 | } 55 | 56 | $this->addResult('vincenty', Timer::get()); 57 | 58 | Timer::reset(); 59 | $bar = new CliProgressBar($repeats); 60 | for ($i = 1; $i <= $repeats; ++$i) { 61 | Timer::start(); 62 | codexworldGetDistance($latitude_from, $longitude_from, $latitude_to, $longitude_to); 63 | Timer::stop(); 64 | $bar->update($i); 65 | } 66 | 67 | $this->addResult('codexworld', Timer::get()); 68 | 69 | Timer::reset(); 70 | $bar = new CliProgressBar($repeats); 71 | for ($i = 1; $i <= $repeats; ++$i) { 72 | Timer::start(); 73 | codexworldGetDistanceOpt($latitude_from, $longitude_from, $latitude_to, $longitude_to); 74 | Timer::stop(); 75 | $bar->update($i); 76 | } 77 | 78 | $this->addResult('codexworld-opt', Timer::get()); 79 | 80 | Timer::reset(); 81 | $bar = new CliProgressBar($repeats); 82 | for ($i = 1; $i <= $repeats; ++$i) { 83 | Timer::start(); 84 | distanceUserChecker($latitude_from, $longitude_from, $latitude_to, $longitude_to); 85 | Timer::stop(); 86 | $bar->update($i); 87 | } 88 | 89 | $this->addResult('custom', Timer::get()); 90 | 91 | Timer::reset(); 92 | $bar = new CliProgressBar($repeats); 93 | for ($i = 1; $i <= $repeats; ++$i) { 94 | Timer::start(); 95 | distanceUserChecker1($latitude_from, $longitude_from, $latitude_to, $longitude_to); 96 | Timer::stop(); 97 | $bar->update($i); 98 | } 99 | 100 | $this->addResult('custom1', Timer::get()); 101 | 102 | Timer::reset(); 103 | $bar = new CliProgressBar($repeats); 104 | for ($i = 1; $i <= $repeats; ++$i) { 105 | Timer::start(); 106 | distanceUserChecker2($latitude_from, $longitude_from, $latitude_to, $longitude_to); 107 | Timer::stop(); 108 | $bar->update($i); 109 | } 110 | 111 | $this->addResult('custom2', Timer::get()); 112 | } 113 | } 114 | 115 | /** 116 | * Calculates the great-circle distance between two points, with 117 | * the Vincenty formula. 118 | * 119 | * @param float $latitudeFrom Latitude of start point in [deg decimal] 120 | * @param float $longitudeFrom Longitude of start point in [deg decimal] 121 | * @param float $latitudeTo Latitude of target point in [deg decimal] 122 | * @param float $longitudeTo Longitude of target point in [deg decimal] 123 | * @param float|int $earthRadius Mean earth radius in [m] 124 | * 125 | * @return float Distance between points in [m] (same as earthRadius) 126 | */ 127 | function vincentyGreatCircleDistance($latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000) 128 | { 129 | // convert from degrees to radians 130 | $latFrom = deg2rad($latitudeFrom); 131 | $lonFrom = deg2rad($longitudeFrom); 132 | $latTo = deg2rad($latitudeTo); 133 | $lonTo = deg2rad($longitudeTo); 134 | $lonDelta = $lonTo - $lonFrom; 135 | 136 | $a = pow(cos($latTo) * sin($lonDelta), 2) + pow(cos($latFrom) * sin($latTo) - sin($latFrom) * cos($latTo) * cos($lonDelta), 2); 137 | $b = sin($latFrom) * sin($latTo) + cos($latFrom) * cos($latTo) * cos($lonDelta); 138 | 139 | $angle = atan2(sqrt($a), $b); 140 | 141 | return $angle * $earthRadius; 142 | } 143 | 144 | /** 145 | * Algorithm got from http://www.codexworld.com/distance-between-two-addresses-google-maps-api-php/ 146 | * 147 | * @param $latitudeFrom 148 | * @param $longitudeFrom 149 | * @param $latitudeTo 150 | * @param $longitudeTo 151 | * 152 | * @return float [km] 153 | */ 154 | function codexworldGetDistance($latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo) 155 | { 156 | //Calculate distance from latitude and longitude 157 | $theta = $longitudeFrom - $longitudeTo; 158 | $dist = sin(deg2rad($latitudeFrom)) * sin(deg2rad($latitudeTo)) + cos(deg2rad($latitudeFrom)) * cos(deg2rad($latitudeTo)) * cos(deg2rad($theta)); 159 | $dist = acos($dist); 160 | $dist = rad2deg($dist); 161 | 162 | return $dist * 60 * 1.852; 163 | } 164 | 165 | /** 166 | * Optimized algorithm from http://www.codexworld.com/distance-between-two-addresses-google-maps-api-php/ 167 | * 168 | * @param $latitudeFrom 169 | * @param $longitudeFrom 170 | * @param $latitudeTo 171 | * @param $longitudeTo 172 | * 173 | * @return float [km] 174 | */ 175 | function codexworldGetDistanceOpt($latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo) 176 | { 177 | $rad = M_PI / 180; 178 | //Calculate distance from latitude and longitude 179 | $theta = $longitudeFrom - $longitudeTo; 180 | $dist = sin($latitudeFrom * $rad) * sin($latitudeTo * $rad) + cos($latitudeFrom * $rad) * cos($latitudeTo * $rad) * cos($theta * $rad); 181 | 182 | return acos($dist) / $rad * 60 * 1.853159616; 183 | } 184 | 185 | /** 186 | * Returns distance in km 187 | * 188 | * @param $lat1 189 | * @param $lng1 190 | * @param $lat2 191 | * @param $lng2 192 | * 193 | * @return float 194 | */ 195 | function distanceUserChecker($lat1, $lng1, $lat2, $lng2) 196 | { 197 | $pi80 = M_PI / 180; 198 | $lat1 *= $pi80; 199 | $lng1 *= $pi80; 200 | $lat2 *= $pi80; 201 | $lng2 *= $pi80; 202 | 203 | $r = 6372.797; // mean radius of Earth in km 204 | $dlat = $lat2 - $lat1; 205 | $dlng = $lng2 - $lng1; 206 | $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2); 207 | $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); 208 | 209 | return $r * $c; 210 | } 211 | 212 | /** 213 | * Returns distance in km 214 | * 215 | * @param $lat1 216 | * @param $lng1 217 | * @param $lat2 218 | * @param $lng2 219 | * 220 | * @return float 221 | */ 222 | function distanceUserChecker1($lat1, $lng1, $lat2, $lng2) 223 | { 224 | $r = 6372.797; // mean radius of Earth in km 225 | $dlat = deg2rad($lat2) - deg2rad($lat1); 226 | $dlng = deg2rad($lng2) - deg2rad($lng1); 227 | $a = sin($dlat / 2) * sin($dlat / 2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dlng / 2) * sin($dlng / 2); 228 | $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); 229 | 230 | return $r * $c; 231 | } 232 | 233 | /** 234 | * Returns distance in km 235 | * 236 | * @param $lat1 237 | * @param $lng1 238 | * @param $lat2 239 | * @param $lng2 240 | * 241 | * @return float 242 | */ 243 | function distanceUserChecker2($lat1, $lng1, $lat2, $lng2) 244 | { 245 | $pi80 = M_PI / 180; 246 | $lat1 *= $pi80; 247 | $lng1 *= $pi80; 248 | $lat2 *= $pi80; 249 | $lng2 *= $pi80; 250 | 251 | $r = 6372.797; // mean radius of Earth in km 252 | $dlat = ($lat2 - $lat1) / 2; 253 | $dlng = ($lng2 - $lng1) / 2; 254 | $a = sin($dlat) * sin($dlat) + cos($lat1) * cos($lat2) * sin($dlng) * sin($dlng); 255 | $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); 256 | 257 | return $r * $c; 258 | } 259 | -------------------------------------------------------------------------------- /Tests/GetClassName.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Thu Dec 01 18:42:13 2016 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class GetClassName 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class GetClassName extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | 35 | Timer::reset(); 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | get_class($this); 40 | Timer::stop(); 41 | $bar->update($i); 42 | } 43 | 44 | $this->addResult('get_class', Timer::get()); 45 | 46 | Timer::reset(); 47 | $bar = new CliProgressBar($repeats); 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | Timer::start(); 50 | self::class; 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('self::class', Timer::get()); 56 | 57 | Timer::reset(); 58 | $bar = new CliProgressBar($repeats); 59 | for ($i = 1; $i <= $repeats; ++$i) { 60 | Timer::start(); 61 | GetClassName::class; 62 | Timer::stop(); 63 | $bar->update($i); 64 | } 65 | 66 | $this->addResult('Class::class', Timer::get()); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Tests/GetFirstArrayElement.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Sat Mar 18 14:30:34 2017 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class GetFirstArrayElement 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class GetFirstArrayElement extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | $array = ['value-1', 'value-2']; 35 | 36 | Timer::reset(); 37 | $bar = new CliProgressBar($repeats); 38 | for ($i = 1; $i <= $repeats; ++$i) { 39 | Timer::start(); 40 | $array[0]; 41 | Timer::stop(); 42 | $bar->update($i); 43 | } 44 | 45 | $this->addResult('Key', Timer::get()); 46 | 47 | Timer::reset(); 48 | $bar = new CliProgressBar($repeats); 49 | for ($i = 1; $i <= $repeats; ++$i) { 50 | Timer::start(); 51 | current($array); 52 | Timer::stop(); 53 | $bar->update($i); 54 | } 55 | 56 | $this->addResult('Current()', Timer::get()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tests/HashBench.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Sat Sep 20 03:37:20 2014 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Veles\Tools\CliProgressBar; 18 | use Veles\Tools\Timer; 19 | use Application\TestApplication; 20 | 21 | /** 22 | * Class HashBench 23 | * 24 | * @author Alexander Yancharuk 25 | */ 26 | class HashBench extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | $string = uniqid(); 34 | $hashes = hash_algos(); 35 | 36 | foreach ($hashes as $hash_name) { 37 | $bar = new CliProgressBar($repeats); 38 | for ($i = 1; $i <= $repeats; ++$i) { 39 | Timer::start(); 40 | hash($hash_name, $string); 41 | Timer::stop(); 42 | $bar->update($i); 43 | } 44 | 45 | $this->addResult($hash_name, Timer::get()); 46 | 47 | Timer::reset(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Tests/IfOptimization.php: -------------------------------------------------------------------------------- 1 | 4 | * @file IfOptimization.php 5 | * 6 | * PHP version 5.4+ 7 | * 8 | * @author Yancharuk Alexander 9 | * @copyright © 2013-2021 Yancharuk Alexander 10 | * @date Thu Jun 02 10:38:50 2016 11 | * @license The BSD 3-Clause License. 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Veles\Tools\CliProgressBar; 18 | use Veles\Tools\Timer; 19 | use Application\TestApplication; 20 | 21 | /** 22 | * Class IfOptimization 23 | * 24 | * @author Yancharuk Alexander 25 | */ 26 | class IfOptimization extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | 34 | $value = rand(0, 255); 35 | $count = 0; 36 | 37 | $bar = new CliProgressBar($repeats); 38 | for ($i = 1; $i <= $repeats; ++$i) { 39 | Timer::start(); 40 | if ($value > 128) { 41 | $count++; 42 | } 43 | Timer::stop(); 44 | $bar->update($i); 45 | } 46 | 47 | $this->addResult('if', Timer::get()); 48 | 49 | Timer::reset(); 50 | $bar = new CliProgressBar($repeats); 51 | for ($i = 1; $i <= $repeats; ++$i) { 52 | Timer::start(); 53 | $count += $value >> 7; 54 | Timer::stop(); 55 | $bar->update($i); 56 | } 57 | 58 | $this->addResult('bit operation', Timer::get()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Tests/IfVsAnd.php: -------------------------------------------------------------------------------- 1 | 10 | * @date 2013-08-24 14:01 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class IfVsAnd 23 | * @author Yancharuk Alexander 24 | */ 25 | class IfVsAnd extends TestApplication 26 | { 27 | protected $repeats = 10000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | 33 | $var = true; 34 | $tmp = false; 35 | 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | if ($var) { 40 | $tmp = $var; 41 | } 42 | Timer::stop(); 43 | $bar->update($i); 44 | } 45 | 46 | $this->addResult('if', Timer::get()); 47 | 48 | $bar = new CliProgressBar($repeats); 49 | 50 | Timer::reset(); 51 | for ($i = 1; $i <= $repeats; ++$i) { 52 | Timer::start(); 53 | $var and $tmp = $var; 54 | Timer::stop(); 55 | $bar->update($i); 56 | } 57 | 58 | $this->addResult('and', Timer::get()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Tests/IncludeFunctionInForeach.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Fri Dec 04 11:10:26 2015 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class IncludeFunctionInForeach 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class IncludeFunctionInForeach extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | $array = range(0,10); 35 | 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | $tmp = array_keys($array); 40 | foreach ($tmp as $value); 41 | Timer::stop(); 42 | $bar->update($i); 43 | } 44 | 45 | unset($tmp, $value); 46 | $this->addResult('Outer function', Timer::get()); 47 | 48 | Timer::reset(); 49 | $bar = new CliProgressBar($repeats); 50 | for ($i = 1; $i <= $repeats; ++$i) { 51 | Timer::start(); 52 | foreach (array_keys($array) as $value); 53 | Timer::stop(); 54 | $bar->update($i); 55 | } 56 | 57 | $this->addResult('Inner function', Timer::get()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Tests/IncludeOnceVsRequireOnce.php: -------------------------------------------------------------------------------- 1 | 10 | * @date 2013-08-31 16:43 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class IncludeOnceVsRequireOnce 23 | * @author Yancharuk Alexander 24 | */ 25 | class IncludeOnceVsRequireOnce extends TestApplication 26 | { 27 | protected $repeats = 10000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | 33 | $bar = new CliProgressBar($repeats); 34 | for ($i = 1; $i <= $repeats; ++$i) { 35 | Timer::start(); 36 | include_once 'ThisVsSelf.php'; 37 | Timer::stop(); 38 | $bar->update($i); 39 | } 40 | 41 | $this->addResult('include_once', Timer::get()); 42 | 43 | Timer::reset(); 44 | $bar = new CliProgressBar($repeats); 45 | for ($i = 1; $i <= $repeats; ++$i) { 46 | Timer::start(); 47 | require_once 'ThisVsSelf.php'; 48 | Timer::stop(); 49 | $bar->update($i); 50 | } 51 | 52 | $this->addResult('require_once', Timer::get()); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Tests/IncludeVsRequire.php: -------------------------------------------------------------------------------- 1 | 10 | * @date 2013-08-04 10:16 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class IncludeVsRequire 23 | * 24 | * @author Yancharuk Alexander 25 | */ 26 | class IncludeVsRequire extends TestApplication 27 | { 28 | protected $repeats = 1; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | 34 | $bar = new CliProgressBar($repeats); 35 | Timer::start(); 36 | include 'ThisVsSelf.php'; 37 | Timer::stop(); 38 | $bar->update(1); 39 | 40 | $this->addResult('include', Timer::get()); 41 | 42 | $bar = new CliProgressBar($repeats); 43 | 44 | Timer::reset(); 45 | Timer::start(); 46 | require 'StrtrVsStrReplace.php'; 47 | Timer::stop(); 48 | $bar->update(1); 49 | 50 | $this->addResult('require', Timer::get()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Tests/IntvalVsTypeCast.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Thu Apr 03 14:39:45 2014 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class IntvalVsTypeCast 23 | * 24 | * @author Alexander Yancharuk 25 | */ 26 | class IntvalVsTypeCast extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | 34 | $bar = new CliProgressBar($repeats); 35 | for ($i = 1; $i <= $repeats; ++$i) { 36 | Timer::start(); 37 | (int) 5.55; 38 | Timer::stop(); 39 | $bar->update($i); 40 | } 41 | 42 | $this->addResult('(int)', Timer::get()); 43 | 44 | Timer::reset(); 45 | $bar = new CliProgressBar($repeats); 46 | for ($i = 1; $i <= $repeats; ++$i) { 47 | Timer::start(); 48 | intval(5.55); 49 | Timer::stop(); 50 | $bar->update($i); 51 | } 52 | 53 | $this->addResult('intval()', Timer::get()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Tests/IsAVsInstanceOf.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Wed Jan 01 11:53:52 2014 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class IsAVsInstanceOf 23 | * 24 | * @author Alexander Yancharuk 25 | */ 26 | class IsAVsInstanceOf extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | $object = new TestClass; 34 | 35 | $bar = new CliProgressBar($repeats); 36 | for ($i = 1; $i <= $repeats; ++$i) { 37 | Timer::start(); 38 | is_a($object, 'TestClass'); 39 | Timer::stop(); 40 | $bar->update($i); 41 | } 42 | 43 | $this->addResult('is_a()', Timer::get()); 44 | 45 | Timer::reset(); 46 | $bar = new CliProgressBar($repeats); 47 | for ($i = 1; $i <= $repeats; ++$i) { 48 | Timer::start(); 49 | $object instanceof TestClass; 50 | Timer::stop(); 51 | $bar->update($i); 52 | } 53 | 54 | $this->addResult('instanceof', Timer::get()); 55 | } 56 | } 57 | 58 | class TestClass 59 | { 60 | private $private; 61 | } 62 | -------------------------------------------------------------------------------- /Tests/JsonVsSerialize.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright © 2013-2021 Yancharuk Alexander 13 | * @date Mon Sep 28 16:56:21 2015 14 | * @license The BSD 3-Clause License 15 | * 16 | */ 17 | 18 | namespace Tests; 19 | 20 | use Veles\Tools\CliProgressBar; 21 | use Veles\Tools\Timer; 22 | use Application\TestApplication; 23 | 24 | /** 25 | * Class JsonVsSerialize 26 | * 27 | * @author Yancharuk Alexander 28 | */ 29 | class JsonVsSerialize extends TestApplication 30 | { 31 | protected $repeats = 10000; 32 | 33 | public function run() 34 | { 35 | $repeats = $this->getRepeats(); 36 | $array = create3DAssocArray(3, 3); 37 | 38 | $bar = new CliProgressBar($repeats); 39 | for ($i = 1; $i <= $repeats; ++$i) { 40 | Timer::start(); 41 | json_encode($array); 42 | Timer::stop(); 43 | $bar->update($i); 44 | } 45 | 46 | $this->addResult('json_encode()', Timer::get()); 47 | 48 | Timer::reset(); 49 | $bar = new CliProgressBar($repeats); 50 | for ($i = 1; $i <= $repeats; ++$i) { 51 | Timer::start(); 52 | serialize($array); 53 | Timer::stop(); 54 | $bar->update($i); 55 | } 56 | 57 | $this->addResult('serialize()', Timer::get()); 58 | 59 | Timer::reset(); 60 | $bar = new CliProgressBar($repeats); 61 | for ($i = 1; $i <= $repeats; ++$i) { 62 | Timer::start(); 63 | var_export($array, true); 64 | Timer::stop(); 65 | $bar->update($i); 66 | } 67 | 68 | $this->addResult('var_export()', Timer::get()); 69 | 70 | Timer::reset(); 71 | $bar = new CliProgressBar($repeats); 72 | for ($i = 1; $i <= $repeats; ++$i) { 73 | Timer::start(); 74 | print_r($array, true); 75 | Timer::stop(); 76 | $bar->update($i); 77 | } 78 | 79 | $this->addResult('print_r()', Timer::get()); 80 | } 81 | } 82 | 83 | /** 84 | * Create x-dimensional associative array 85 | * 86 | * @param int $max Max dimension 87 | * @param int $elements Max elements in each dimension 88 | * @param int $dim Current dimension 89 | * 90 | * @return array 91 | */ 92 | function create3DAssocArray($max = 3, $elements = 100, $dim = 0) 93 | { 94 | $i = 0; 95 | $array = []; 96 | 97 | while (++$i <= $elements) { 98 | $key = md5(uniqid()); 99 | $tmp = $dim; 100 | 101 | $array[$key] = ($tmp !== $max) 102 | ? create3DAssocArray($max, $elements, ++$tmp) 103 | : md5(uniqid()); 104 | } 105 | 106 | return $array; 107 | } 108 | -------------------------------------------------------------------------------- /Tests/JsonVsSerializeInt.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Tue Sep 29 16:05:45 2015 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class JsonVsSerializeInt 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class JsonVsSerializeInt extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | $array = create3DNumArray(3, 5); 35 | 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | json_encode($array); 40 | Timer::stop(); 41 | $bar->update($i); 42 | } 43 | 44 | $this->addResult('json_encode()', Timer::get()); 45 | 46 | Timer::reset(); 47 | $bar = new CliProgressBar($repeats); 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | Timer::start(); 50 | serialize($array); 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('serialize()', Timer::get()); 56 | 57 | Timer::reset(); 58 | $bar = new CliProgressBar($repeats); 59 | for ($i = 1; $i <= $repeats; ++$i) { 60 | Timer::start(); 61 | var_export($array, true); 62 | Timer::stop(); 63 | $bar->update($i); 64 | } 65 | 66 | $this->addResult('var_export()', Timer::get()); 67 | 68 | Timer::reset(); 69 | $bar = new CliProgressBar($repeats); 70 | for ($i = 1; $i <= $repeats; ++$i) { 71 | Timer::start(); 72 | print_r($array, true); 73 | Timer::stop(); 74 | $bar->update($i); 75 | } 76 | 77 | $this->addResult('print_r()', Timer::get()); 78 | } 79 | } 80 | 81 | /** 82 | * Create x-dimensional numeric array 83 | * 84 | * @param int $max Max dimension 85 | * @param int $elements Max elements in each dimension 86 | * @param int $dim Current dimension 87 | * 88 | * @return array 89 | */ 90 | function create3DNumArray($max = 3, $elements = 100, $dim = 0) 91 | { 92 | $i = 0; 93 | $array = []; 94 | 95 | while (++$i <= $elements) { 96 | $key = $i; 97 | $tmp = $dim; 98 | 99 | $array[$key] = ($tmp !== $max) 100 | ? create3DNumArray($max, $elements, ++$tmp) 101 | : rand(); 102 | } 103 | 104 | return $array; 105 | } 106 | -------------------------------------------------------------------------------- /Tests/ListVsSubstr.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Пнд Сен 16 15:31:22 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class ListVsSubstr 23 | * @author Yancharuk Alexander 24 | */ 25 | class ListVsSubstr extends TestApplication 26 | { 27 | protected $repeats = 1000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | $text = 'Administration\Controller\UserController::Save'; 33 | 34 | $bar = new CliProgressBar($repeats); 35 | for ($i = 1; $i <= $repeats; ++$i) { 36 | Timer::start(); 37 | list($module) = explode('::', $text); 38 | Timer::stop(); 39 | $bar->update($i); 40 | } 41 | 42 | $this->addResult('list+explode', Timer::get()); 43 | 44 | $bar = new CliProgressBar($repeats); 45 | 46 | Timer::reset(); 47 | for ($i = 1; $i <= $repeats; ++$i) { 48 | Timer::start(); 49 | $module = substr($text, 0, strpos($text, '::')); 50 | Timer::stop(); 51 | $bar->update($i); 52 | } 53 | 54 | $this->addResult('substr+strpos', Timer::get()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Tests/MagicVsDefinitionGet.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Sat Mar 18 14:11:52 2017 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class MagicVsDefinitionGet 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class MagicVsDefinitionGet extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | 35 | Timer::reset(); 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | $obj = new MagicGet; 39 | Timer::start(); 40 | $obj->name; 41 | Timer::stop(); 42 | $bar->update($i); 43 | } 44 | 45 | $this->addResult('Magic get', Timer::get()); 46 | 47 | Timer::reset(); 48 | $bar = new CliProgressBar($repeats); 49 | for ($i = 1; $i <= $repeats; ++$i) { 50 | $obj = new DefinedGet; 51 | Timer::start(); 52 | $obj->getName(); 53 | Timer::stop(); 54 | $bar->update($i); 55 | } 56 | 57 | $this->addResult('Defined get', Timer::get()); 58 | } 59 | } 60 | 61 | class MagicGet 62 | { 63 | private $data = ['name' => 'Nico']; 64 | 65 | public function __get($prop) 66 | { 67 | return isset($this->data[$prop]) ? $this->data[$prop] : null; 68 | } 69 | } 70 | 71 | class DefinedGet 72 | { 73 | protected $name = 'Nico'; 74 | 75 | /** 76 | * @return string 77 | */ 78 | public function getName() 79 | { 80 | return $this->name; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Tests/MagicVsDefinitionSet.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Sat Mar 18 14:11:52 2017 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class MagicVsDefinitionSet 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class MagicVsDefinitionSet extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | $value = 'Chad'; 35 | 36 | Timer::reset(); 37 | $bar = new CliProgressBar($repeats); 38 | for ($i = 1; $i <= $repeats; ++$i) { 39 | $obj = new MagicSet; 40 | Timer::start(); 41 | $obj->name = $value; 42 | Timer::stop(); 43 | $bar->update($i); 44 | } 45 | 46 | $this->addResult('Magic set', Timer::get()); 47 | 48 | Timer::reset(); 49 | $bar = new CliProgressBar($repeats); 50 | for ($i = 1; $i <= $repeats; ++$i) { 51 | $obj = new DefinedSet; 52 | Timer::start(); 53 | $obj->setName($value); 54 | Timer::stop(); 55 | $bar->update($i); 56 | } 57 | 58 | $this->addResult('Defined set', Timer::get()); 59 | } 60 | } 61 | 62 | class MagicSet 63 | { 64 | private $data = ['name' => 'Nico']; 65 | 66 | public function __set($prop, $value) 67 | { 68 | if (isset($this->data[$prop])) { 69 | $this->data[$prop] = $value; 70 | } 71 | } 72 | } 73 | 74 | class DefinedSet 75 | { 76 | protected $name = 'Nico'; 77 | 78 | /** 79 | * @param string $name 80 | */ 81 | public function setName($name) 82 | { 83 | $this->name = $name; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Tests/MysqlVsMysqliVsPdoRead.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Fri Sep 27 13:06:09 2013 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Application\DbConnectException; 19 | use Application\DbQueryException; 20 | use Application\TestApplication; 21 | use mysqli; 22 | use PDO; 23 | use Veles\Tools\CliProgressBar; 24 | use Veles\Tools\Timer; 25 | 26 | /** 27 | * Class MysqlVsMysqliVsPdoRead 28 | * 29 | * @author Yancharuk Alexander 30 | */ 31 | class MysqlVsMysqliVsPdoRead extends TestApplication 32 | { 33 | protected $class_dependencies = ['PDO', 'MySQLi']; 34 | protected $ext_dependencies = ['pdo_mysql', 'mysqli']; 35 | 36 | protected $repeats = 1000; 37 | protected $result_format = "%-30s%-16s%-16s%-16s\n"; 38 | 39 | private static $user = 'root'; 40 | private static $host = 'localhost'; 41 | private static $password = ''; 42 | private static $database = 'php_bench_test'; 43 | 44 | public function run() 45 | { 46 | $this->prepareTables(); 47 | $repeats = $this->getRepeats(); 48 | 49 | $sql = 'SELECT txt FROM test'; 50 | $bar = new CliProgressBar($repeats); 51 | 52 | $mysqli = new mysqli( 53 | self::$host, self::$user, self::$password, self::$database 54 | ); 55 | for ($i = 1; $i <= $repeats; ++$i) { 56 | $result = []; 57 | Timer::start(); 58 | $res = $mysqli->query($sql); 59 | while ($row = $res->fetch_assoc()) $result[] = $row; 60 | Timer::stop(); 61 | $bar->update($i); 62 | } 63 | 64 | $res->free(); 65 | $this->addResult('MySQLi', Timer::get()); 66 | 67 | $bar = new CliProgressBar($repeats); 68 | 69 | Timer::reset(); 70 | $link = mysqli_connect( 71 | self::$host, self::$user, self::$password, self::$database 72 | ); 73 | for ($i = 1; $i <= $repeats; ++$i) { 74 | $result = []; 75 | Timer::start(); 76 | $res = mysqli_query($link, $sql); 77 | while ($row = mysqli_fetch_row($res)) $result[] = $row; 78 | Timer::stop(); 79 | $bar->update($i); 80 | } 81 | 82 | mysqli_close($link); 83 | $this->addResult('Non-object MySQLi', Timer::get()); 84 | 85 | $bar = new CliProgressBar($repeats); 86 | 87 | Timer::reset(); 88 | $link = mysqli_connect( 89 | self::$host, self::$user, self::$password, self::$database 90 | ); 91 | for ($i = 1; $i <= $repeats; ++$i) { 92 | $result = []; 93 | Timer::start(); 94 | $res = mysqli_query($link, $sql, MYSQLI_USE_RESULT); 95 | while ($row = mysqli_fetch_row($res)) $result[] = $row; 96 | Timer::stop(); 97 | $bar->update($i); 98 | } 99 | 100 | mysqli_close($link); 101 | $this->addResult('Non-object unbuffered MySQLi', Timer::get()); 102 | 103 | $bar = new CliProgressBar($repeats); 104 | 105 | Timer::reset(); 106 | $dsn = 'mysql:dbname=' . self::$database . ';' 107 | . 'host=' . self::$host . ';' 108 | . 'charset=utf8'; 109 | $pdo = new PDO($dsn, self::$user, self::$password); 110 | $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 111 | for ($i = 1; $i <= $repeats; ++$i) { 112 | $result = []; 113 | Timer::start(); 114 | foreach ($pdo->query($sql) as $row) $result[] = $row; 115 | Timer::stop(); 116 | $bar->update($i); 117 | } 118 | 119 | $this->addResult('PDO', Timer::get()); 120 | $bar = new CliProgressBar($repeats); 121 | $pdo = new PDO($dsn, self::$user, self::$password); 122 | $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 123 | 124 | Timer::reset(); 125 | for ($i = 1; $i <= $repeats; ++$i) { 126 | Timer::start(); 127 | $stmt = $pdo->query($sql); 128 | $result = $stmt->fetchAll(); 129 | Timer::stop(); 130 | $bar->update($i); 131 | } 132 | 133 | $this->addResult('PDO fetchAll()', Timer::get()); 134 | 135 | $bar = new CliProgressBar($repeats); 136 | $pdo = new PDO($dsn, self::$user, self::$password); 137 | $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 138 | 139 | Timer::reset(); 140 | for ($i = 1; $i <= $repeats; ++$i) { 141 | Timer::start(); 142 | $stmt = $pdo->prepare($sql); 143 | $stmt->execute(); 144 | foreach ($stmt as $row) $result[] = $row; 145 | Timer::stop(); 146 | $bar->update($i); 147 | $result = []; 148 | } 149 | 150 | $this->addResult('PDO execute()', Timer::get()); 151 | $this->cleanup(); 152 | } 153 | 154 | /** 155 | * Prepares tables with data for test 156 | * 157 | * @throws \Application\DbQueryException 158 | * @throws \Application\DbConnectException 159 | */ 160 | public function prepareTables() 161 | { 162 | $mysqli = new mysqli(self::$host, self::$user, self::$password); 163 | if ($mysqli->connect_errno) { 164 | throw new DbConnectException( 165 | "Connect Error ($mysqli->connect_errno)\n$mysqli->connect_error" 166 | ); 167 | } 168 | 169 | $mysqli->query('CREATE DATABASE IF NOT EXISTS ' . self::$database); 170 | if ($mysqli->errno) { 171 | throw new DbQueryException( 172 | "Query Error ($mysqli->errno)\n$mysqli->error" 173 | ); 174 | } 175 | 176 | $mysqli->select_db(self::$database); 177 | $mysqli->query(" 178 | CREATE TABLE IF NOT EXISTS test ( 179 | id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 180 | txt CHAR(50) NOT NULL DEFAULT '' 181 | ) ENGINE INNODB 182 | "); 183 | if ($mysqli->errno) { 184 | throw new DbQueryException( 185 | "Query Error ($mysqli->errno)\n$mysqli->error" 186 | ); 187 | } 188 | 189 | $arr = []; 190 | $i = 0; 191 | while (++$i <= 1000) { 192 | $arr[] = uniqid('test-value::'); 193 | } 194 | 195 | $values = implode("'),('", $arr); 196 | $sql = "INSERT INTO test (txt) VALUES ('$values')"; 197 | $mysqli->query($sql); 198 | if ($mysqli->errno) { 199 | throw new DbQueryException( 200 | "Query Error ($mysqli->errno)\n$mysqli->error" 201 | ); 202 | } 203 | } 204 | 205 | /** 206 | * Cleanup database 207 | * 208 | * @throws \Application\DbQueryException 209 | * @throws \Application\DbConnectException 210 | */ 211 | public function cleanup() 212 | { 213 | $mysqli = new mysqli(self::$host, self::$user, self::$password); 214 | if ($mysqli->connect_errno) { 215 | throw new DbConnectException( 216 | "Connect Error ($mysqli->connect_errno)\n$mysqli->connect_error" 217 | ); 218 | } 219 | 220 | $mysqli->query('DROP DATABASE ' . self::$database); 221 | if ($mysqli->errno) { 222 | throw new DbQueryException( 223 | "Query Error ($mysqli->errno)\n$mysqli->error" 224 | ); 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /Tests/MysqlVsMysqliVsPdoWrite.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Fri Oct 02 12:33:15 2015 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Application\DbConnectException; 19 | use Application\DbQueryException; 20 | use Application\TestApplication; 21 | use mysqli; 22 | use PDO; 23 | use Veles\Tools\CliProgressBar; 24 | use Veles\Tools\Timer; 25 | 26 | /** 27 | * Class MysqlVsMysqliVsPdoWrite 28 | * 29 | * @author Yancharuk Alexander 30 | */ 31 | class MysqlVsMysqliVsPdoWrite extends TestApplication 32 | { 33 | protected $class_dependencies = ['PDO', 'MySQLi']; 34 | protected $ext_dependencies = ['pdo_mysql', 'mysqli']; 35 | 36 | private $user = 'root'; 37 | private $host = 'localhost'; 38 | private $password = ''; 39 | private $database = 'php_bench_test'; 40 | 41 | protected $repeats = 1000; 42 | protected $result_format = "%-25s%-16s%-16s%-16s\n"; 43 | 44 | public function run() 45 | { 46 | $this->prepareTables(); 47 | $repeats = $this->getRepeats(); 48 | 49 | $bar = new CliProgressBar($repeats); 50 | $value = uniqid(); 51 | $sql = "INSERT INTO test (txt) VALUES ('$value')"; 52 | 53 | $mysqli = new mysqli( 54 | $this->host, $this->user, $this->password, $this->database 55 | ); 56 | for ($i = 1; $i <= $repeats; ++$i) { 57 | Timer::start(); 58 | $mysqli->query($sql); 59 | Timer::stop(); 60 | $bar->update($i); 61 | } 62 | 63 | $this->addResult('MySQLi', Timer::get()); 64 | 65 | Timer::reset(); 66 | $bar = new CliProgressBar($repeats); 67 | 68 | $link = mysqli_connect( 69 | $this->host, $this->user, $this->password, $this->database 70 | ); 71 | for ($i = 1; $i <= $repeats; ++$i) { 72 | Timer::start(); 73 | mysqli_query($link, $sql); 74 | Timer::stop(); 75 | $bar->update($i); 76 | } 77 | 78 | $this->addResult('Non-object MySQLi', Timer::get()); 79 | 80 | Timer::reset(); 81 | $bar = new CliProgressBar($repeats); 82 | 83 | $dsn = 'mysql:dbname=' . $this->database . ';' 84 | . 'host=' . $this->host . ';' 85 | . 'charset=utf8'; 86 | $pdo = new PDO($dsn, $this->user, $this->password); 87 | $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 88 | for ($i = 1; $i <= $repeats; ++$i) { 89 | Timer::start(); 90 | $pdo->query($sql); 91 | Timer::stop(); 92 | $bar->update($i); 93 | } 94 | 95 | $this->addResult('PDO', Timer::get()); 96 | 97 | $this->cleanup(); 98 | } 99 | 100 | /** 101 | * Prepares tables with data for test 102 | * 103 | * @throws \Application\DbQueryException 104 | * @throws \Application\DbConnectException 105 | */ 106 | public function prepareTables() 107 | { 108 | $mysqli = new mysqli($this->host, $this->user, $this->password); 109 | if ($mysqli->connect_errno) { 110 | throw new DbConnectException( 111 | "Connect Error ($mysqli->connect_errno)\n$mysqli->connect_error" 112 | ); 113 | } 114 | 115 | $mysqli->query('CREATE DATABASE IF NOT EXISTS ' . $this->database); 116 | if ($mysqli->errno) { 117 | throw new DbQueryException( 118 | "Query Error ($mysqli->errno)\n$mysqli->error" 119 | ); 120 | } 121 | 122 | $mysqli->select_db($this->database); 123 | $mysqli->query(" 124 | CREATE TABLE IF NOT EXISTS test ( 125 | id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 126 | txt CHAR(50) NOT NULL DEFAULT '' 127 | ) ENGINE INNODB 128 | "); 129 | if ($mysqli->errno) { 130 | throw new DbQueryException( 131 | "Query Error ($mysqli->errno)\n$mysqli->error" 132 | ); 133 | } 134 | 135 | $arr = []; 136 | $i = 0; 137 | while (++$i <= 1000) { 138 | $arr[] = uniqid('test-value::'); 139 | } 140 | 141 | $values = implode("'),('", $arr); 142 | $sql = "INSERT INTO test (txt) VALUES ('$values')"; 143 | $mysqli->query($sql); 144 | if ($mysqli->errno) { 145 | throw new DbQueryException( 146 | "Query Error ($mysqli->errno)\n$mysqli->error" 147 | ); 148 | } 149 | } 150 | 151 | /** 152 | * Cleanup database 153 | * 154 | * @throws \Application\DbQueryException 155 | * @throws \Application\DbConnectException 156 | */ 157 | public function cleanup() 158 | { 159 | $mysqli = new mysqli($this->host, $this->user, $this->password); 160 | if ($mysqli->connect_errno) { 161 | throw new DbConnectException( 162 | "Connect Error ($mysqli->connect_errno)\n$mysqli->connect_error" 163 | ); 164 | } 165 | 166 | $mysqli->query('DROP DATABASE ' . $this->database); 167 | if ($mysqli->errno) { 168 | throw new DbQueryException( 169 | "Query Error ($mysqli->errno)\n$mysqli->error" 170 | ); 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /Tests/PdoEmulatedPlaceholders.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Tue Jan 28 11:59:34 2014 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\DbConnectException; 18 | use Application\DbQueryException; 19 | use Application\TestApplication; 20 | use mysqli; 21 | use PDO; 22 | use Veles\DataBase\Adapters\PdoAdapter; 23 | use Veles\DataBase\Db; 24 | use Veles\Tools\CliProgressBar; 25 | use Veles\Tools\Timer; 26 | 27 | /** 28 | * Class PdoEmulatedPlaceholders 29 | * 30 | * @author Alexander Yancharuk 31 | */ 32 | class PdoEmulatedPlaceholders extends TestApplication 33 | { 34 | protected $class_dependencies = ['PDO', 'MySQLi']; 35 | protected $ext_dependencies = ['pdo_mysql', 'mysqli']; 36 | 37 | protected $repeats = 1000; 38 | private $user = 'root'; 39 | private $host = 'localhost'; 40 | private $password = ''; 41 | private $database = 'php_bench_test'; 42 | 43 | public function run() 44 | { 45 | $this->prepareTables(); 46 | $repeats = $this->getRepeats(); 47 | $value1 = 'string one'; 48 | $value2 = 'string two'; 49 | $value3 = 'string three'; 50 | 51 | 52 | $bar = new CliProgressBar($repeats); 53 | for ($i = 1; $i <= $repeats; ++$i) { 54 | Timer::start(); 55 | $sql = ' 56 | INSERT INTO test (txt) VALUES 57 | (?), 58 | (?), 59 | (?) 60 | '; 61 | Db::query($sql, [$value1, $value2, $value3]); 62 | Timer::stop(); 63 | $bar->update($i); 64 | } 65 | 66 | $this->addResult('Real', Timer::get()); 67 | 68 | Db::getAdapter()->getResource() 69 | ->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); 70 | Timer::reset(); 71 | $bar = new CliProgressBar($repeats); 72 | for ($i = 1; $i <= $repeats; ++$i) { 73 | Timer::start(); 74 | $sql = ' 75 | INSERT INTO test (txt) VALUES 76 | (?), 77 | (?), 78 | (?) 79 | '; 80 | Db::query($sql, [$value1, $value2, $value3]); 81 | Timer::stop(); 82 | $bar->update($i); 83 | } 84 | 85 | $this->addResult('Emulated', Timer::get()); 86 | $this->cleanup(); 87 | } 88 | 89 | public function prepareTables() 90 | { 91 | $mysqli = new mysqli($this->host, $this->user, $this->password); 92 | if ($mysqli->connect_errno) { 93 | throw new DbConnectException( 94 | "Connect Error ($mysqli->connect_errno)\n$mysqli->connect_error" 95 | ); 96 | } 97 | 98 | $mysqli->query('CREATE DATABASE IF NOT EXISTS ' . $this->database); 99 | if ($mysqli->errno) { 100 | throw new DbQueryException( 101 | "Query Error ($mysqli->errno)\n$mysqli->error" 102 | ); 103 | } 104 | 105 | $mysqli->select_db($this->database); 106 | 107 | $sql = "CREATE TABLE IF NOT EXISTS test ( 108 | id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 109 | txt CHAR(50) NOT NULL DEFAULT '' 110 | ) ENGINE INNODB"; 111 | $mysqli->query($sql); 112 | } 113 | 114 | public function cleanup() 115 | { 116 | $mysqli = new mysqli($this->host, $this->user, $this->password); 117 | if ($mysqli->connect_errno) { 118 | throw new DbConnectException( 119 | "Connect Error ($mysqli->connect_errno)\n$mysqli->connect_error" 120 | ); 121 | } 122 | 123 | $mysqli->query('DROP DATABASE ' . $this->database); 124 | if ($mysqli->errno) { 125 | throw new DbQueryException( 126 | "Query Error ($mysqli->errno)\n$mysqli->error" 127 | ); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /Tests/PharAutoLoad.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Sun Apr 23 09:27:03 2017 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class PharAutoLoad 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class PharAutoLoad extends TestApplication 28 | { 29 | protected $repeats = 1; 30 | protected $ext_dependencies = ['Phar']; 31 | 32 | public function run() 33 | { 34 | $repeats = $this->getRepeats(); 35 | 36 | Timer::reset(); 37 | $bar = new CliProgressBar($repeats); 38 | for ($i = 1; $i <= $repeats; ++$i) { 39 | Timer::start(); 40 | new \NotPhar\ClassOne; 41 | new \NotPhar\ClassTwo; 42 | new \NotPhar\ClassThree; 43 | new \NotPhar\ClassFour; 44 | new \NotPhar\ClassFive; 45 | new \NotPhar\ClassSix; 46 | new \NotPhar\ClassSeven; 47 | new \NotPhar\ClassEight; 48 | new \NotPhar\ClassNine; 49 | new \NotPhar\ClassTen; 50 | Timer::stop(); 51 | $bar->update($i); 52 | } 53 | 54 | $this->addResult('not phar', Timer::get()); 55 | 56 | Timer::reset(); 57 | $bar = new CliProgressBar($repeats); 58 | // unregister PSR-autoloader for clean performance results 59 | spl_autoload_unregister(['Veles\AutoLoader', 'load']); 60 | 61 | require __DIR__ . '/../lib/archive.phar'; 62 | 63 | for ($i = 1; $i <= $repeats; ++$i) { 64 | Timer::start(); 65 | new \Phar\ClassOne; 66 | new \Phar\ClassTwo; 67 | new \Phar\ClassThree; 68 | new \Phar\ClassFour; 69 | new \Phar\ClassFive; 70 | new \Phar\ClassSix; 71 | new \Phar\ClassSeven; 72 | new \Phar\ClassEight; 73 | new \Phar\ClassNine; 74 | new \Phar\ClassTen; 75 | Timer::stop(); 76 | $bar->update($i); 77 | } 78 | 79 | spl_autoload_register(['Veles\AutoLoader', 'load']); 80 | $this->addResult('phar', Timer::get()); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Tests/PharMultiCall.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Sun Apr 23 10:50:39 2017 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class PharMultiCall 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class PharMultiCall extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | // Required Phar extension 31 | protected $ext_dependencies = ['Phar']; 32 | 33 | public function run() 34 | { 35 | $repeats = $this->getRepeats(); 36 | 37 | Timer::reset(); 38 | $bar = new CliProgressBar($repeats); 39 | for ($i = 1; $i <= $repeats; ++$i) { 40 | Timer::start(); 41 | new \NotPhar\ClassOne; 42 | new \NotPhar\ClassTwo; 43 | new \NotPhar\ClassThree; 44 | new \NotPhar\ClassFour; 45 | new \NotPhar\ClassFive; 46 | new \NotPhar\ClassSix; 47 | new \NotPhar\ClassSeven; 48 | new \NotPhar\ClassEight; 49 | new \NotPhar\ClassNine; 50 | new \NotPhar\ClassTen; 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('not phar', Timer::get()); 56 | 57 | Timer::reset(); 58 | $bar = new CliProgressBar($repeats); 59 | // unregister PSR-autoloader for clean performance results 60 | spl_autoload_unregister(['Veles\AutoLoader', 'load']); 61 | 62 | require __DIR__ . '/../lib/archive.phar'; 63 | 64 | for ($i = 1; $i <= $repeats; ++$i) { 65 | Timer::start(); 66 | new \Phar\ClassOne; 67 | new \Phar\ClassTwo; 68 | new \Phar\ClassThree; 69 | new \Phar\ClassFour; 70 | new \Phar\ClassFive; 71 | new \Phar\ClassSix; 72 | new \Phar\ClassSeven; 73 | new \Phar\ClassEight; 74 | new \Phar\ClassNine; 75 | new \Phar\ClassTen; 76 | Timer::stop(); 77 | $bar->update($i); 78 | } 79 | 80 | spl_autoload_register(['Veles\AutoLoader', 'load']); 81 | $this->addResult('phar', Timer::get()); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Tests/RandVsMtRand.php: -------------------------------------------------------------------------------- 1 | 10 | * @date 2013-08-04 10:16 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class RandVsMtRand 23 | * @author Yancharuk Alexander 24 | */ 25 | class RandVsMtRand extends TestApplication 26 | { 27 | protected $repeats = 10000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | 33 | $bar = new CliProgressBar($repeats); 34 | for ($i = 1; $i <= $repeats; ++$i) { 35 | Timer::start(); 36 | rand(); 37 | Timer::stop(); 38 | $bar->update($i); 39 | } 40 | 41 | $this->addResult('rand', Timer::get()); 42 | 43 | $bar = new CliProgressBar($repeats); 44 | Timer::reset(); 45 | for ($i = 1; $i <= $repeats; ++$i) { 46 | Timer::start(); 47 | mt_rand(); 48 | Timer::stop(); 49 | $bar->update($i); 50 | } 51 | 52 | $this->addResult('mt_rand', Timer::get()); 53 | 54 | $bar = new CliProgressBar($repeats); 55 | Timer::reset(); 56 | for ($i = 1; $i <= $repeats; ++$i) { 57 | Timer::start(); 58 | random_int(PHP_INT_MIN, PHP_INT_MAX); 59 | Timer::stop(); 60 | $bar->update($i); 61 | } 62 | 63 | $this->addResult('random_int', Timer::get()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Tests/RecursiveArrayIteratorPerformance.php: -------------------------------------------------------------------------------- 1 | 11 | * @date Thu Dec 12 10:06:42 2013 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Application\TestApplication; 19 | use RecursiveArrayIterator; 20 | use RecursiveIteratorIterator; 21 | use Veles\Tools\CliProgressBar; 22 | use Veles\Tools\Timer; 23 | 24 | /** 25 | * Class RecursiveArrayIteratorPerformance 26 | * 27 | * @author Alexander Yancharuk 28 | */ 29 | class RecursiveArrayIteratorPerformance extends TestApplication 30 | { 31 | protected $repeats = 10000; 32 | 33 | public function run() 34 | { 35 | $repeats = $this->getRepeats(); 36 | 37 | $last_leave = ''; 38 | $array = create3DAssocArray(3, 10); 39 | 40 | $leaves = new RecursiveIteratorIterator( 41 | new RecursiveArrayIterator($array), 42 | RecursiveIteratorIterator::LEAVES_ONLY 43 | ); 44 | 45 | foreach ($leaves as $leave) $last_leave = $leave; 46 | 47 | $it = new RecursiveIteratorIterator( 48 | new RecursiveArrayIterator($array) 49 | ); 50 | 51 | $bar = new CliProgressBar($repeats); 52 | for ($i = 1; $i <= $repeats; ++$i) { 53 | Timer::start(); 54 | checkIterator($last_leave, $it); 55 | Timer::stop(); 56 | $bar->update($i); 57 | } 58 | 59 | $this->addResult('Iterator', Timer::get()); 60 | 61 | Timer::reset(); 62 | $bar = new CliProgressBar($repeats); 63 | for ($i = 1; $i <= $repeats; ++$i) { 64 | Timer::start(); 65 | checkKeyIsInArray($last_leave, $array); 66 | Timer::stop(); 67 | $bar->update($i); 68 | } 69 | 70 | $this->addResult('Custom func', Timer::get()); 71 | } 72 | } 73 | 74 | /** 75 | * Create x-dimensional associative array 76 | * 77 | * @param int $max Max dimension 78 | * @param int $elements Max elements in each dimension 79 | * @param int $dim Current dimension 80 | * @return array 81 | */ 82 | function create3DAssocArray($max = 3, $elements = 100, $dim = 0) 83 | { 84 | $i = 0; 85 | $array = []; 86 | 87 | while (++$i <= $elements) { 88 | $key = uniqid('key::'); 89 | $tmp = $dim; 90 | 91 | $array[$key] = ($tmp !== $max) 92 | ? create3DAssocArray($max, $elements, ++$tmp) 93 | : uniqid('value::'); 94 | } 95 | 96 | return $array; 97 | } 98 | 99 | /** 100 | * Function for search nested key using RecursiveIteratorIterator 101 | * 102 | * @param string $needle String for search in keys 103 | * @param \RecursiveIteratorIterator $iterator 104 | * @return bool 105 | * @see http://stackoverflow.com/questions/20530359/php-find-key-in-nested-associtive-array 106 | */ 107 | function checkIterator ($needle, RecursiveIteratorIterator $iterator) 108 | { 109 | foreach ($iterator as $value) { 110 | if ($needle === $value) return true; 111 | } 112 | return false; 113 | } 114 | 115 | /** 116 | * Function proposed for search nested key 117 | * 118 | * @param $dataItemName 119 | * @param $array 120 | * @return bool 121 | * @see http://stackoverflow.com/questions/20530359/php-find-key-in-nested-associtive-array 122 | */ 123 | function checkKeyIsInArray($dataItemName, $array) 124 | { 125 | foreach ($array as $key => $value) { 126 | if ((string) $key == $dataItemName) 127 | return true; 128 | if (is_array($value) && checkKeyIsInArray($dataItemName, $value)) 129 | return true; 130 | } 131 | 132 | return false; 133 | } 134 | -------------------------------------------------------------------------------- /Tests/RecursiveDirectoryScan.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Thu Aug 14 11:12:31 2014 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class RecursiveDirectoryScan 23 | * 24 | * @author Alexander Yancharuk 25 | */ 26 | class RecursiveDirectoryScan extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | 34 | $dir = self::createDir(); 35 | 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | recursive_read_dir($dir); 40 | Timer::stop(); 41 | $bar->update($i); 42 | } 43 | 44 | $this->addResult('readdir()', Timer::get()); 45 | 46 | Timer::reset(); 47 | $bar = new CliProgressBar($repeats); 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | Timer::start(); 50 | recursive_dir($dir); 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('dir()', Timer::get()); 56 | 57 | Timer::reset(); 58 | $bar = new CliProgressBar($repeats); 59 | for ($i = 1; $i <= $repeats; ++$i) { 60 | Timer::start(); 61 | recursive_scan_dir($dir); 62 | Timer::stop(); 63 | $bar->update($i); 64 | } 65 | 66 | $this->addResult('scandir()', Timer::get()); 67 | 68 | Timer::reset(); 69 | $bar = new CliProgressBar($repeats); 70 | for ($i = 1; $i <= $repeats; ++$i) { 71 | Timer::start(); 72 | recursive_diff_scan_dir($dir); 73 | Timer::stop(); 74 | $bar->update($i); 75 | } 76 | 77 | $this->addResult('diff scandir()', Timer::get()); 78 | 79 | Timer::reset(); 80 | $bar = new CliProgressBar($repeats); 81 | for ($i = 1; $i <= $repeats; ++$i) { 82 | Timer::start(); 83 | recursive_iterator($dir); 84 | Timer::stop(); 85 | $bar->update($i); 86 | } 87 | 88 | $this->addResult('iterator', Timer::get()); 89 | 90 | Timer::reset(); 91 | $bar = new CliProgressBar($repeats); 92 | for ($i = 1; $i <= $repeats; ++$i) { 93 | Timer::start(); 94 | recursive_glob($dir); 95 | Timer::stop(); 96 | $bar->update($i); 97 | } 98 | 99 | $this->addResult('glob()', Timer::get()); 100 | 101 | self::dirCleanup($dir); 102 | } 103 | 104 | /** 105 | * Method for create multidimensional directory with files 106 | * 107 | * @param null|string $name Directory name 108 | * @param int $max Max dimension 109 | * @param int $files Max files in each dimension 110 | * @param int $dirs Create directories quantity 111 | * @param int $dim Current dimension 112 | * 113 | * @throws \Exception 114 | * @return string Return root directory name 115 | */ 116 | public function createDir( 117 | $name = null, $max = 3, $files = 30, $dirs = 3, $dim = 0 118 | ) { 119 | if ($max < $dim) return $name; 120 | 121 | if (null === $name && 0 === $dim) { 122 | $dir = __DIR__ . uniqid('/dir-'); 123 | mkdir($dir, 0777, true); 124 | self::createDir($dir, $max, $files, $dirs, $dim + 1); 125 | 126 | return $dir; 127 | } 128 | 129 | $i = $dirs; 130 | while (--$i >= 0) { 131 | $dir = $name . uniqid('/dir-'); 132 | mkdir($dir, 0777, true); 133 | self::createDir($dir, $max, $files, $dirs, $dim + 1); 134 | } 135 | 136 | while (--$files >= 0) { 137 | $file_name = $name . uniqid('/file-') . '.tmp'; 138 | fopen($file_name, 'w'); 139 | } 140 | 141 | return $name; 142 | } 143 | 144 | /** 145 | * Method for cleanup multidimensional directory with files 146 | * 147 | * @param string $dir Directory name for cleanup 148 | */ 149 | public function dirCleanup($dir) 150 | { 151 | foreach (scandir($dir) as $name) { 152 | if ('..' === $name or '.' === $name) continue; 153 | 154 | $path = "$dir/$name"; 155 | 156 | if (is_dir($path) and is_writable($path)) { 157 | self::dirCleanup($path); 158 | continue; 159 | } 160 | 161 | unlink($path); 162 | } 163 | 164 | rmdir($dir); 165 | } 166 | } 167 | 168 | function recursive_read_dir($dir) { 169 | $result = []; 170 | 171 | $handle = opendir($dir); 172 | while (false !== ($file = readdir($handle))) { 173 | if ('..' === $file or '.' === $file) continue; 174 | if (is_dir("$dir/$file")) { 175 | $result = array_merge( 176 | $result, recursive_read_dir("$dir/$file") 177 | ); 178 | } else { 179 | $result[] = $file; 180 | } 181 | } 182 | closedir($handle); 183 | 184 | return $result; 185 | } 186 | 187 | function recursive_dir($dir) { 188 | $result = []; 189 | 190 | $directory = dir($dir); 191 | while (false !== ($file = $directory->read())) { 192 | if ('..' === $file or '.' === $file) continue; 193 | if (is_dir("$dir/$file")) { 194 | $result = array_merge( 195 | $result, recursive_dir("$dir/$file") 196 | ); 197 | } else { 198 | $result[] = $file; 199 | } 200 | } 201 | 202 | return $result; 203 | } 204 | 205 | function recursive_scan_dir($dir) { 206 | $result = []; 207 | 208 | foreach (scandir($dir) as $file) { 209 | if ('..' === $file or '.' === $file) continue; 210 | if (is_dir("$dir/$file")) { 211 | $result = array_merge( 212 | $result, recursive_scan_dir("$dir/$file") 213 | ); 214 | } else { 215 | $result[] = $file; 216 | } 217 | } 218 | 219 | return $result; 220 | } 221 | 222 | function recursive_diff_scan_dir($dir) { 223 | $result = []; 224 | 225 | foreach (array_diff(scandir($dir), ['..', '.']) as $file) { 226 | if (is_dir("$dir/$file")) { 227 | $result = array_merge( 228 | $result, recursive_diff_scan_dir("$dir/$file") 229 | ); 230 | } else { 231 | $result[] = $file; 232 | } 233 | } 234 | 235 | return $result; 236 | } 237 | 238 | function recursive_iterator($dir) { 239 | $result = []; 240 | 241 | $iterator = new \RecursiveIteratorIterator( 242 | new \RecursiveDirectoryIterator($dir, 243 | \FilesystemIterator::SKIP_DOTS 244 | | \FilesystemIterator::KEY_AS_FILENAME 245 | ) 246 | ); 247 | foreach ($iterator as $filename => $file_info) { 248 | $result[] = $filename; 249 | } 250 | return $result; 251 | } 252 | 253 | function recursive_glob($dir) { 254 | $result = []; 255 | 256 | foreach (glob("$dir/*") as $file) { 257 | if (is_dir($file)) { 258 | $result = array_merge( 259 | $result, recursive_glob($file) 260 | ); 261 | } else { 262 | $result[] = $file; 263 | } 264 | } 265 | 266 | return $result; 267 | } 268 | -------------------------------------------------------------------------------- /Tests/RegexNamedSubPatterns.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Sun Nov 01 13:47:51 2015 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class RegexNamedSubPatterns 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class RegexNamedSubPatterns extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | protected $result_format = "%-30s%-16s%-16s%-16s\n"; 31 | 32 | public function run() 33 | { 34 | $repeats = $this->getRepeats(); 35 | 36 | $uri = '/book/category/344/user/5443'; 37 | $regex = '#^/book/category/(\d+)/user/(\d+)$#'; 38 | $named_regex = '#^/book/category/(?P\d+)/user/(?P\d+)$#'; 39 | $named_regex_alt1 = '#^/book/category/(?\d+)/user/(?\d+)$#'; 40 | $named_regex_alt2 = '#^/book/category/(?\'category_id\'\d+)/user/(?\'user_id\'\d+)$#'; 41 | 42 | $bar = new CliProgressBar($repeats); 43 | for ($i = 1; $i <= $repeats; ++$i) { 44 | Timer::start(); 45 | preg_match($regex, $uri, $matches); 46 | Timer::stop(); 47 | $bar->update($i); 48 | } 49 | 50 | $this->addResult('regex', Timer::get()); 51 | 52 | Timer::reset(); 53 | $bar = new CliProgressBar($repeats); 54 | for ($i = 1; $i <= $repeats; ++$i) { 55 | Timer::start(); 56 | preg_match($named_regex, $uri, $matches); 57 | Timer::stop(); 58 | $bar->update($i); 59 | } 60 | 61 | $this->addResult('named regex (?P)', Timer::get()); 62 | 63 | Timer::reset(); 64 | $bar = new CliProgressBar($repeats); 65 | for ($i = 1; $i <= $repeats; ++$i) { 66 | Timer::start(); 67 | preg_match($named_regex_alt1, $uri, $matches); 68 | Timer::stop(); 69 | $bar->update($i); 70 | } 71 | 72 | $this->addResult('named regex (?)', Timer::get()); 73 | 74 | Timer::reset(); 75 | $bar = new CliProgressBar($repeats); 76 | for ($i = 1; $i <= $repeats; ++$i) { 77 | Timer::start(); 78 | preg_match($named_regex_alt2, $uri, $matches); 79 | Timer::stop(); 80 | $bar->update($i); 81 | } 82 | 83 | $this->addResult('named regex (?\'name\')', Timer::get()); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Tests/RemoveSpaceFromString.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Thu Oct 06 12:25:56 2016 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class RemoveSpaceFromString 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class RemoveSpaceFromString extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | $string = 'this is string with spaces'; 35 | 36 | Timer::reset(); 37 | $result = ''; 38 | $bar = new CliProgressBar($repeats); 39 | for ($i = 1; $i <= $repeats; ++$i) { 40 | Timer::start(); 41 | $result = str_replace(' ', '', $string); 42 | Timer::stop(); 43 | $bar->update($i); 44 | } 45 | 46 | $this->addResult('str_replace', Timer::get()); 47 | 48 | Timer::reset(); 49 | $result = ''; 50 | $bar = new CliProgressBar($repeats); 51 | for ($i = 1; $i <= $repeats; ++$i) { 52 | Timer::start(); 53 | $result = preg_replace('/\s+/', '', $string); 54 | Timer::stop(); 55 | $bar->update($i); 56 | } 57 | 58 | $this->addResult('preg_replace', Timer::get()); 59 | 60 | Timer::reset(); 61 | $result = ''; 62 | $bar = new CliProgressBar($repeats); 63 | for ($i = 1; $i <= $repeats; ++$i) { 64 | Timer::start(); 65 | $result = strtok($string, ' '); 66 | while (false !== ($substr = strtok(' '))) 67 | $result .= $substr; 68 | Timer::stop(); 69 | $bar->update($i); 70 | } 71 | 72 | $this->addResult('strtok', Timer::get()); 73 | 74 | Timer::reset(); 75 | $result = ''; 76 | $bar = new CliProgressBar($repeats); 77 | for ($i = 1; $i <= $repeats; ++$i) { 78 | Timer::start(); 79 | $j = 0; 80 | $length = strlen($string); 81 | while ($j < $length) { 82 | if (' ' === $string[$j]) { 83 | ++$j; continue; 84 | } 85 | 86 | $result .= $string[$j]; 87 | ++$j; 88 | } 89 | 90 | Timer::stop(); 91 | $bar->update($i); 92 | } 93 | 94 | $this->addResult('str as array', Timer::get()); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Tests/ReturnArrayVsObject.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Sat Sep 20 15:04:55 2014 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Veles\Tools\CliProgressBar; 18 | use Veles\Tools\Timer; 19 | use Application\TestApplication; 20 | 21 | /** 22 | * Class ReturnArrayVsObject 23 | * 24 | * @author Alexander Yancharuk 25 | */ 26 | class ReturnArrayVsObject extends TestApplication 27 | { 28 | protected $repeats = 1000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | $prop_name = 'property'; 34 | $prop_count = 30; 35 | 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | $result = static::returnArray($prop_count, $prop_name); 40 | Timer::stop(); 41 | $bar->update($i); 42 | } 43 | 44 | $this->addResult('return array', Timer::get()); 45 | 46 | Timer::reset(); 47 | $bar = new CliProgressBar($repeats); 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | $arr = static::createArray($prop_count, $prop_name); 50 | Timer::start(); 51 | static::fillArray($arr, $prop_count, $prop_name); 52 | Timer::stop(); 53 | $bar->update($i); 54 | } 55 | 56 | $this->addResult('fill array', Timer::get()); 57 | 58 | Timer::reset(); 59 | $bar = new CliProgressBar($repeats); 60 | for ($i = 1; $i <= $repeats; ++$i) { 61 | $obj = static::createObject($prop_count, $prop_name); 62 | Timer::start(); 63 | static::fillObject($obj, $prop_count, $prop_name); 64 | Timer::stop(); 65 | $bar->update($i); 66 | } 67 | 68 | $this->addResult('fill object', Timer::get()); 69 | } 70 | 71 | private static function fillObject($obj, $count, $prop_name) 72 | { 73 | $i = 0; 74 | while (++$i <= $count) { 75 | $obj->{$prop_name . $i} = uniqid(); 76 | } 77 | } 78 | 79 | private static function createObject($count, $prop_name) 80 | { 81 | $obj = new \StdClass; 82 | 83 | $i = 0; 84 | while (++$i <= $count) { 85 | $obj->{$prop_name . $i} = ''; 86 | } 87 | 88 | return $obj; 89 | } 90 | 91 | private static function createArray($count, $prop_name) 92 | { 93 | $arr = []; 94 | $i = 0; 95 | while (++$i <= $count) { 96 | $arr[$prop_name . $i] = ''; 97 | } 98 | 99 | return $arr; 100 | } 101 | 102 | private static function fillArray(array &$arr, $count, $prop_name) 103 | { 104 | $i = 0; 105 | while (++$i <= $count) { 106 | $arr[$prop_name . $i] = uniqid(); 107 | } 108 | } 109 | 110 | private static function returnArray($count, $prop_name) 111 | { 112 | $arr = []; 113 | $i = 0; 114 | while (++$i <= $count) { 115 | $arr[$prop_name . $i] = uniqid(); 116 | } 117 | 118 | return $arr; 119 | } 120 | } 121 | 122 | -------------------------------------------------------------------------------- /Tests/RoundToNearestThousand.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Wed Jan 01 11:12:36 2014 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class RoundToNearestThousand 23 | * 24 | * @author Alexander Yancharuk 25 | */ 26 | class RoundToNearestThousand extends TestApplication 27 | { 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $repeats = $this->getRepeats(); 33 | $x = mt_rand(1, 999); 34 | 35 | $bar = new CliProgressBar($repeats); 36 | for ($i = 1; $i <= $repeats; ++$i) { 37 | Timer::start(); 38 | round($x, -3); 39 | Timer::stop(); 40 | $bar->update($i); 41 | } 42 | 43 | $this->addResult('round', Timer::get()); 44 | 45 | Timer::reset(); 46 | $bar = new CliProgressBar($repeats); 47 | for ($i = 1; $i <= $repeats; ++$i) { 48 | Timer::start(); 49 | ($x + 500) / 1000 * 1000; 50 | Timer::stop(); 51 | $bar->update($i); 52 | } 53 | 54 | $this->addResult('calculation', Timer::get()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Tests/SelfVsClass.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Сбт Фев 16 17:01:16 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class SelfVsClass 23 | * @author Yancharuk Alexander 24 | */ 25 | class SelfVsClass extends TestApplication 26 | { 27 | const TEST = 'simple value'; 28 | protected $repeats = 10000; 29 | 30 | public function run() 31 | { 32 | $a = 0; 33 | $repeats = $this->getRepeats(); 34 | $bar = new CliProgressBar($repeats); 35 | for ($i = 1; $i <= $repeats; ++$i) { 36 | Timer::start(); 37 | $a = self::TEST; 38 | Timer::stop(); 39 | $bar->update($i); 40 | } 41 | 42 | $this->addResult('self::TEST', Timer::get()); 43 | 44 | $bar = new CliProgressBar($repeats); 45 | 46 | $a = 0; 47 | Timer::reset(); 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | Timer::start(); 50 | $a = SelfVsClass::TEST; 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('class::TEST', Timer::get()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Tests/SplFixedArrayVsArrayAdd.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright © 2013-2021 Yancharuk Alexander 12 | * @date Sat Mar 25 08:52:02 2017 13 | * @license The BSD 3-Clause License. 14 | * 15 | */ 16 | 17 | namespace Tests; 18 | 19 | use SplFixedArray; 20 | use Veles\Tools\CliProgressBar; 21 | use Veles\Tools\Timer; 22 | use Application\TestApplication; 23 | 24 | /** 25 | * Class SplFixedArrayVsArrayAdd 26 | * 27 | * @author Yancharuk Alexander 28 | */ 29 | class SplFixedArrayVsArrayAdd extends TestApplication 30 | { 31 | protected $repeats = 10000; 32 | 33 | public function run() 34 | { 35 | $repeats = $this->getRepeats(); 36 | $size = 1000; 37 | 38 | Timer::reset(); 39 | $bar = new CliProgressBar($repeats); 40 | for ($i = 1; $i <= $repeats; ++$i) { 41 | $array = new SplFixedArray($size); 42 | Timer::start(); 43 | for ($j = 0; $j < $size; ++$j) { 44 | $array[$j] = $i; 45 | } 46 | Timer::stop(); 47 | $bar->update($i); 48 | } 49 | 50 | $this->addResult('SplFixedArray', Timer::get()); 51 | 52 | Timer::reset(); 53 | $bar = new CliProgressBar($repeats); 54 | for ($i = 1; $i <= $repeats; ++$i) { 55 | $array = []; 56 | Timer::start(); 57 | for ($j = 0; $j < $size; ++$j) { 58 | $array[] = $j; 59 | } 60 | Timer::stop(); 61 | $bar->update($i); 62 | } 63 | 64 | $this->addResult('Array', Timer::get()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Tests/SplFixedArrayVsArrayCreate.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Sat Mar 25 09:09:51 2017 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use SplFixedArray; 19 | use Veles\Tools\CliProgressBar; 20 | use Veles\Tools\Timer; 21 | use Application\TestApplication; 22 | 23 | /** 24 | * Class SplFixedArrayVsArrayCreate 25 | * 26 | * @author Yancharuk Alexander 27 | */ 28 | class SplFixedArrayVsArrayCreate extends TestApplication 29 | { 30 | protected $repeats = 10000; 31 | 32 | public function run() 33 | { 34 | $repeats = $this->getRepeats(); 35 | $size = 1000; 36 | 37 | Timer::reset(); 38 | $bar = new CliProgressBar($repeats); 39 | for ($i = 1; $i <= $repeats; ++$i) { 40 | Timer::start(); 41 | $array = new SplFixedArray($size); 42 | Timer::stop(); 43 | $bar->update($i); 44 | } 45 | 46 | $this->addResult('SplFixedArray', Timer::get()); 47 | 48 | Timer::reset(); 49 | $bar = new CliProgressBar($repeats); 50 | for ($i = 1; $i <= $repeats; ++$i) { 51 | Timer::start(); 52 | $array = []; 53 | Timer::stop(); 54 | $bar->update($i); 55 | } 56 | 57 | $this->addResult('Array', Timer::get()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Tests/SplFixedArrayVsArrayGet.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright © 2013-2021 Yancharuk Alexander 12 | * @date Sat Mar 25 09:12:31 2017 13 | * @license The BSD 3-Clause License. 14 | * 15 | */ 16 | 17 | namespace Tests; 18 | 19 | use SplFixedArray; 20 | use Veles\Tools\CliProgressBar; 21 | use Veles\Tools\Timer; 22 | use Application\TestApplication; 23 | 24 | /** 25 | * Class SplFixedArrayVsArrayGet 26 | * 27 | * @author Yancharuk Alexander 28 | */ 29 | class SplFixedArrayVsArrayGet extends TestApplication 30 | { 31 | protected $repeats = 10000; 32 | 33 | public function run() 34 | { 35 | $repeats = $this->getRepeats(); 36 | $size = 1000; 37 | $array = range(1, $size); 38 | $fixed = SplFixedArray::fromArray($array); 39 | 40 | Timer::reset(); 41 | $bar = new CliProgressBar($repeats); 42 | for ($i = 1; $i <= $repeats; ++$i) { 43 | $idx = rand(0, $size - 1); 44 | Timer::start(); 45 | $array[$idx]; 46 | Timer::stop(); 47 | $bar->update($i); 48 | } 49 | 50 | $this->addResult('Array', Timer::get()); 51 | 52 | Timer::reset(); 53 | $bar = new CliProgressBar($repeats); 54 | for ($i = 1; $i <= $repeats; ++$i) { 55 | $idx = rand(0, $size - 1); 56 | Timer::start(); 57 | $fixed[$idx]; 58 | Timer::stop(); 59 | $bar->update($i); 60 | } 61 | 62 | $this->addResult('SplFixedArray', Timer::get()); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Tests/StrRepeatFillPerformance.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Thu Nov 09 15:45:27 2017 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class StrRepeatFillPerformance 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class StrRepeatFillPerformance extends TestApplication 28 | { 29 | protected $repeats = 10000; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | 35 | Timer::reset(); 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | str_repeat('0000000000', 1639); 40 | Timer::stop(); 41 | $bar->update($i); 42 | } 43 | 44 | $this->addResult('Multi-byte parameter', Timer::get()); 45 | 46 | Timer::reset(); 47 | $bar = new CliProgressBar($repeats); 48 | for ($i = 1; $i <= $repeats; ++$i) { 49 | Timer::start(); 50 | str_repeat('0', 16390); 51 | Timer::stop(); 52 | $bar->update($i); 53 | } 54 | 55 | $this->addResult('Single-byte parameter', Timer::get()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Tests/StringGenBench.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Втр Сен 10 16:03:47 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class StringGenBench 23 | * @author Yancharuk Alexander 24 | */ 25 | class StringGenBench extends TestApplication 26 | { 27 | protected $repeats = 1000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | 33 | $bar = new CliProgressBar($repeats); 34 | for ($i = 1; $i <= $repeats; ++$i) { 35 | Timer::start(); 36 | genStrShuffle(); 37 | Timer::stop(); 38 | $bar->update($i); 39 | } 40 | 41 | $this->addResult('genStr', Timer::get()); 42 | 43 | $bar = new CliProgressBar($repeats); 44 | 45 | Timer::reset(); 46 | for ($i = 1; $i <= $repeats; ++$i) { 47 | Timer::start(); 48 | genStrArr(); 49 | Timer::stop(); 50 | $bar->update($i); 51 | } 52 | 53 | $this->addResult('genStrOpt', Timer::get()); 54 | } 55 | } 56 | 57 | function genStrShuffle( 58 | $length = 22, 59 | $letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./' 60 | ) { 61 | return substr(str_shuffle(str_repeat($letters, 5)), 0, $length); 62 | } 63 | 64 | function genStrArr( 65 | $length = 22, 66 | $letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./' 67 | ) { 68 | $str_len = strlen($letters) - 1; 69 | $result = ''; 70 | $i = 0; 71 | while (++$i <= $length) { $result .= $letters[mt_rand(0, $str_len)]; } 72 | 73 | return $result; 74 | } 75 | -------------------------------------------------------------------------------- /Tests/StrposVsStrstr.php: -------------------------------------------------------------------------------- 1 | 10 | * @date Wed Oct 2 16:42:55 2013 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class StrposVsStrstr 23 | * @author Yancharuk Alexander 24 | */ 25 | class StrposVsStrstr extends TestApplication 26 | { 27 | protected $repeats = 10000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | 33 | $string = 'This is test string'; 34 | $needle = 'is test'; 35 | 36 | $bar = new CliProgressBar($repeats); 37 | for ($i = 1; $i <= $repeats; ++$i) { 38 | Timer::start(); 39 | strpos($string, $needle); 40 | Timer::stop(); 41 | $bar->update($i); 42 | } 43 | 44 | $this->addResult('strpos', Timer::get()); 45 | 46 | $bar = new CliProgressBar($repeats); 47 | 48 | Timer::reset(); 49 | for ($i = 1; $i <= $repeats; ++$i) { 50 | Timer::start(); 51 | strstr($string, $needle); 52 | Timer::stop(); 53 | $bar->update($i); 54 | } 55 | 56 | $this->addResult('strstr', Timer::get()); 57 | 58 | $bar = new CliProgressBar($repeats); 59 | 60 | Timer::reset(); 61 | for ($i = 1; $i <= $repeats; ++$i) { 62 | Timer::start(); 63 | substr($string, 0, strlen($needle)); 64 | Timer::stop(); 65 | $bar->update($i); 66 | } 67 | 68 | $this->addResult('substr+strlen', Timer::get()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Tests/StrtrVsStrReplace.php: -------------------------------------------------------------------------------- 1 | 10 | * @date 2013-08-04 10:16 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class StrtrVsStrReplace 23 | * @author Yancharuk Alexander 24 | */ 25 | class StrtrVsStrReplace extends TestApplication 26 | { 27 | protected $repeats = 1000; 28 | 29 | public function run() 30 | { 31 | $repeats = $this->getRepeats(); 32 | 33 | $namespace = 'Vendor\Package\Core'; 34 | $bar = new CliProgressBar($repeats); 35 | for ($i = 1; $i <= $repeats; ++$i) { 36 | Timer::start(); 37 | strtr($namespace, ['\\' => DIRECTORY_SEPARATOR]); 38 | Timer::stop(); 39 | $bar->update($i); 40 | } 41 | 42 | $this->addResult('strtr', Timer::get()); 43 | 44 | $bar = new CliProgressBar($repeats); 45 | 46 | Timer::reset(); 47 | for ($i = 1; $i <= $repeats; ++$i) { 48 | Timer::start(); 49 | str_replace('\\', DIRECTORY_SEPARATOR, $namespace); 50 | Timer::stop(); 51 | $bar->update($i); 52 | } 53 | 54 | $this->addResult('str_replace', Timer::get()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Tests/ThisVsSelf.php: -------------------------------------------------------------------------------- 1 | 10 | * @date 2013-08-04 10:16 11 | * @license The BSD 3-Clause License 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Application\TestApplication; 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | 21 | /** 22 | * Class ThisVsSelf 23 | * @author Yancharuk Alexander 24 | */ 25 | class ThisVsSelf extends TestApplication 26 | { 27 | public function run() 28 | { 29 | $repeats = 100000; 30 | $bar = new CliProgressBar($repeats); 31 | for ($i = 1; $i <= $repeats; ++$i) { 32 | Timer::start(); 33 | $var = new Test; 34 | Timer::stop(); 35 | $bar->update($i); 36 | } 37 | 38 | $this->addResult('This', Timer::get()); 39 | 40 | $bar = new CliProgressBar($repeats); 41 | 42 | Timer::reset(); 43 | for ($i = 1; $i <= $repeats; ++$i) { 44 | Timer::start(); 45 | $var = new TestSelf; 46 | Timer::stop(); 47 | $bar->update($i); 48 | } 49 | 50 | $this->addResult('Self', Timer::get()); 51 | } 52 | } 53 | 54 | class Test 55 | { 56 | public function __construct() 57 | { 58 | $this->testMethod(); 59 | } 60 | 61 | public function testMethod() 62 | { 63 | return true; 64 | } 65 | } 66 | 67 | class TestSelf 68 | { 69 | public function __construct() 70 | { 71 | self::testMethod(); 72 | } 73 | 74 | public function testMethod() 75 | { 76 | return true; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Tests/Translite.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright © 2013-2021 Yancharuk Alexander 10 | * @date Wed Apr 17 14:00:05 2019 11 | * @license The BSD 3-Clause License. 12 | * 13 | */ 14 | 15 | namespace Tests; 16 | 17 | use Veles\Tools\CliProgressBar; 18 | use Veles\Tools\Timer; 19 | use Application\TestApplication; 20 | 21 | /** 22 | * Class Translite 23 | * 24 | * @author Yancharuk Alexander 25 | */ 26 | class Translite extends TestApplication 27 | { 28 | protected $ext_dependencies = ['intl']; 29 | 30 | protected $repeats = 10000; 31 | 32 | public function run() 33 | { 34 | $repeats = $this->getRepeats(); 35 | $value = 'Всем привет!'; 36 | 37 | Timer::reset(); 38 | $bar = new CliProgressBar($repeats); 39 | for ($i = 1; $i <= $repeats; ++$i) { 40 | Timer::start(); 41 | transliterator_transliterate('Any-Latin;Latin-ASCII;', $value); 42 | Timer::stop(); 43 | $bar->update($i); 44 | } 45 | 46 | $this->addResult('Intl', Timer::get()); 47 | 48 | Timer::reset(); 49 | $bar = new CliProgressBar($repeats); 50 | for ($i = 1; $i <= $repeats; ++$i) { 51 | Timer::start(); 52 | transliterate($value); 53 | Timer::stop(); 54 | $bar->update($i); 55 | } 56 | 57 | $this->addResult('Custom', Timer::get()); 58 | 59 | Timer::reset(); 60 | $bar = new CliProgressBar($repeats); 61 | for ($i = 1; $i <= $repeats; ++$i) { 62 | Timer::start(); 63 | (new StringTransliterator)->fromRussianToEnglish($value); 64 | Timer::stop(); 65 | $bar->update($i); 66 | } 67 | 68 | $this->addResult('Custom class', Timer::get()); 69 | } 70 | } 71 | 72 | function transliterate($string) 73 | { 74 | $cyr = [ 75 | 'а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п', 76 | 'р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я', 77 | 'А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П', 78 | 'Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я',' ' 79 | ]; 80 | $lat = [ 81 | 'a','b','v','g','d','e','io','zh','z','i','y','k','l','m','n','o','p', 82 | 'r','s','t','u','f','h','ts','ch','sh','sht','a','i','y','e','yu','ya', 83 | 'A','B','V','G','D','E','Io','Zh','Z','I','Y','K','L','M','N','O','P', 84 | 'R','S','T','U','F','H','Ts','Ch','Sh','Sht','A','I','Y','e','Yu','Ya','_' 85 | ]; 86 | 87 | return str_replace($cyr, $lat, $string); 88 | } 89 | 90 | 91 | /** 92 | * Class StringTransliterator 93 | */ 94 | class StringTransliterator 95 | { 96 | private const RUSSIAN_SYMBOLS = [ 97 | 'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 98 | 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я', 99 | 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 100 | 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я', ' ' 101 | ]; 102 | 103 | private const LATIN_SYMBOLS = [ 104 | 'a', 'b', 'v', 'g', 'd', 'e', 'yo', 'zh', 'z', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 105 | 'r', 's', 't', 'u', 'f', 'h', 'cz', 'ch', 'sh', 'shh', 'a', 'y', 'y', 'e', 'yu', 'ya', 106 | 'A', 'B', 'V', 'G', 'D', 'E', 'Yo', 'Zh', 'Z', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 107 | 'R', 'S', 'T', 'U', 'F', 'H', 'Cz', 'Ch', 'Sh', 'Shh', 'A', 'Y', 'Y', 'E', 'Yu', 'Ya', '_' 108 | ]; 109 | 110 | /** 111 | * @param string $string 112 | * @return string 113 | */ 114 | public function fromRussianToEnglish(string $string): string 115 | { 116 | return str_replace(static::RUSSIAN_SYMBOLS, static::LATIN_SYMBOLS, $string); 117 | } 118 | 119 | /** 120 | * @param string $string 121 | * @return string 122 | */ 123 | public function fromEnglishToRussian(string $string): string 124 | { 125 | $latin = []; 126 | $russian = []; 127 | foreach (static::LATIN_SYMBOLS as $key => $symbol) { 128 | $latin[strlen($symbol)][] = $symbol; 129 | $russian[strlen($symbol)][] = static::RUSSIAN_SYMBOLS[$key]; 130 | } 131 | for ($i = 3; $i > 0; $i--) { 132 | $string = str_replace($latin[$i], $russian[$i], $string); 133 | } 134 | return $string; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /Tests/UniqueNumbers.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2013-2021 Yancharuk Alexander 11 | * @date Fri Jul 12 06:22:17 2019 12 | * @license The BSD 3-Clause License. 13 | * 14 | */ 15 | 16 | namespace Tests; 17 | 18 | use Veles\Tools\CliProgressBar; 19 | use Veles\Tools\Timer; 20 | use Application\TestApplication; 21 | 22 | /** 23 | * Class UniqueNumbers 24 | * 25 | * @author Yancharuk Alexander 26 | */ 27 | class UniqueNumbers extends TestApplication 28 | { 29 | protected $repeats = 10; 30 | 31 | public function run() 32 | { 33 | $repeats = $this->getRepeats(); 34 | $minValue = 20000; 35 | $maxValue = 2000000; 36 | $count = 1000000; 37 | 38 | Timer::reset(); 39 | $bar = new CliProgressBar($repeats); 40 | for ($i = 1; $i <= $repeats; ++$i) { 41 | Timer::start(); 42 | generateWithShuffle($minValue, $maxValue, $count); 43 | Timer::stop(); 44 | $bar->update($i); 45 | } 46 | 47 | $this->addResult('shuffle()', Timer::get()); 48 | 49 | Timer::reset(); 50 | $bar = new CliProgressBar($repeats); 51 | for ($i = 1; $i <= $repeats; ++$i) { 52 | Timer::start(); 53 | generateWithKeys($minValue, $maxValue, $count); 54 | Timer::stop(); 55 | $bar->update($i); 56 | } 57 | 58 | $this->addResult('keys', Timer::get()); 59 | 60 | Timer::reset(); 61 | $bar = new CliProgressBar($repeats); 62 | for ($i = 1; $i <= $repeats; ++$i) { 63 | Timer::start(); 64 | generateWithValues($minValue, $maxValue, $count); 65 | Timer::stop(); 66 | $bar->update($i); 67 | } 68 | 69 | $this->addResult('values', Timer::get()); 70 | } 71 | } 72 | 73 | function generateWithShuffle($minValue, $maxValue, $count) { 74 | $numbers = range($minValue, $maxValue); 75 | shuffle($numbers); 76 | 77 | return array_slice($numbers, 0, $count); 78 | } 79 | 80 | function generateWithKeys($minValue, $maxValue, $count) { 81 | $result = []; 82 | 83 | while(count($result) < $count) { 84 | $result[rand($minValue, $maxValue)] = true; 85 | } 86 | 87 | return array_keys($result); 88 | } 89 | 90 | function generateWithValues($minValue, $maxValue, $count) { 91 | $result = []; 92 | $i = 0; 93 | 94 | while($i++ < $count) { 95 | while(in_array($num = mt_rand($minValue, $maxValue), $result)); 96 | $result[] = $num; 97 | } 98 | 99 | return $result; 100 | } 101 | -------------------------------------------------------------------------------- /lib/DataBase/Adapters/DbAdapterBase.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date 2013-12-31 15:44 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase\Adapters; 17 | 18 | use DataBase\ConnectionPools\ConnectionPool; 19 | use Veles\Traits\SingletonInstance; 20 | 21 | /** 22 | * Class DbAdapterBase 23 | * 24 | * Base class for Db adapters 25 | * 26 | * @author Alexander Yancharuk 27 | */ 28 | class DbAdapterBase 29 | { 30 | /** @var ConnectionPool */ 31 | protected static $pool; 32 | /** @var \PDO */ 33 | protected static $connection; 34 | /** @var string */ 35 | protected static $connection_name; 36 | 37 | use SingletonInstance; 38 | 39 | /** 40 | * Add connection pool 41 | * 42 | * @param ConnectionPool $pool 43 | */ 44 | public static function setPool(ConnectionPool $pool) 45 | { 46 | static::$pool = $pool; 47 | static::$connection_name = $pool->getDefaultConnectionName(); 48 | } 49 | 50 | /** 51 | * Get connection pool 52 | * 53 | * @return ConnectionPool $pool 54 | */ 55 | public static function getPool() 56 | { 57 | return static::$pool; 58 | } 59 | 60 | /** 61 | * Set default connection 62 | * 63 | * @param string $name Connection name 64 | * 65 | * @return $this 66 | */ 67 | public function setConnection($name) 68 | { 69 | static::$connection_name = $name; 70 | static::$connection = null; 71 | 72 | return $this; 73 | } 74 | 75 | /** 76 | * Get default connection resource 77 | * 78 | * return \PDO 79 | */ 80 | public function getConnection() 81 | { 82 | if (null === static::$connection) { 83 | $conn = static::$pool->getConnection(static::$connection_name); 84 | static::$connection = (null === $conn->getResource()) 85 | ? $conn->create() 86 | : $conn->getResource(); 87 | } 88 | 89 | return static::$connection; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lib/DataBase/Adapters/PdoAdapter.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date 2013-12-31 15:44 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase\Adapters; 17 | 18 | use PDO; 19 | use DataBase\Exceptions\DbException; 20 | 21 | /** 22 | * Class PdoAdapter 23 | * 24 | * Adapter PDO extension 25 | * 26 | * @author Alexander Yancharuk 27 | */ 28 | class PdoAdapter extends DbAdapterBase implements iDbAdapter 29 | { 30 | // Save statement for ability to get error information 31 | /** @var \PDOStatement */ 32 | private $stmt; 33 | 34 | private $type = [ 35 | 'i' => PDO::PARAM_INT, 36 | 'd' => PDO::PARAM_STR, 37 | 's' => PDO::PARAM_STR, 38 | 'b' => PDO::PARAM_LOB 39 | ]; 40 | 41 | private function bindParams(array $params, $types) 42 | { 43 | foreach ($params as $key => $param) { 44 | $type = isset($this->type[$types[$key]]) 45 | ? $this->type[$types[$key]] 46 | : PDO::PARAM_STR; 47 | // Placeholder numbers begins from 1 48 | $this->stmt->bindValue($key + 1, $param, $type); 49 | } 50 | } 51 | 52 | private function prepare($sql, array $params, $types) 53 | { 54 | $this->stmt = $this->getConnection()->prepare($sql); 55 | 56 | if (null === $types) { 57 | $this->stmt->execute($params); 58 | } else { 59 | $this->bindParams($params, $types); 60 | $this->stmt->execute(); 61 | } 62 | } 63 | 64 | /** 65 | * Throw DbException with query info 66 | * 67 | * @param string $sql 68 | * @param array $params 69 | * @param \PDOException $e 70 | * 71 | * @throws DbException 72 | */ 73 | private function throwExceptionWithInfo($sql, array $params, \PDOException $e) 74 | { 75 | $exception = new DbException($e->getMessage(), (int) $e->getCode(), $e); 76 | $exception->setSql($sql); 77 | $exception->setParams($params); 78 | 79 | throw $exception; 80 | } 81 | 82 | /** 83 | * Get value from table row 84 | * 85 | * @param string $sql SQL-query 86 | * @param array $params Query values 87 | * @param string|null $types Placeholders types 88 | * 89 | * @return mixed 90 | */ 91 | public function value($sql, array $params, $types) 92 | { 93 | $result = ''; 94 | 95 | try { 96 | $this->prepare($sql, $params, $types); 97 | $result = $this->stmt->fetchColumn(); 98 | } catch (\PDOException $e) { 99 | $this->throwExceptionWithInfo($sql, $params, $e); 100 | } 101 | 102 | return $result; 103 | } 104 | 105 | /** 106 | * Get table row 107 | * 108 | * @param string $sql SQL-query 109 | * @param array $params Query values 110 | * @param string|null $types Placeholders types 111 | * 112 | * @return mixed 113 | */ 114 | public function row($sql, array $params, $types) 115 | { 116 | $result = []; 117 | 118 | try { 119 | $this->prepare($sql, $params, $types); 120 | $result = $this->stmt->fetch(); 121 | } catch (\PDOException $e) { 122 | $this->throwExceptionWithInfo($sql, $params, $e); 123 | } 124 | 125 | return $result; 126 | } 127 | 128 | /** 129 | * Get result collection 130 | * 131 | * @param string $sql SQL-query 132 | * @param array $params Query values 133 | * @param string|null $types Placeholders types 134 | * 135 | * @return mixed 136 | */ 137 | public function rows($sql, array $params, $types) 138 | { 139 | $result = []; 140 | 141 | try { 142 | $this->prepare($sql, $params, $types); 143 | $result = function () { 144 | yield $this->stmt->fetch(); 145 | }; 146 | } catch (\PDOException $e) { 147 | $this->throwExceptionWithInfo($sql, $params, $e); 148 | } 149 | 150 | return $result; 151 | } 152 | 153 | /** 154 | * Transaction initialization 155 | * 156 | * @return bool 157 | * @throws DbException 158 | */ 159 | public function begin() 160 | { 161 | try { 162 | $result = $this->getConnection()->beginTransaction(); 163 | } catch (\PDOException $e) { 164 | throw new DbException($e->getMessage(), (int) $e->getCode(), $e); 165 | } 166 | return $result; 167 | } 168 | 169 | /** 170 | * Transaction rollback 171 | * 172 | * @return bool 173 | * @throws DbException 174 | */ 175 | public function rollback() 176 | { 177 | try { 178 | $result = $this->getConnection()->rollBack(); 179 | } catch (\PDOException $e) { 180 | throw new DbException($e->getMessage(), (int) $e->getCode(), $e); 181 | } 182 | return $result; 183 | } 184 | 185 | /** 186 | * Commit transaction 187 | * 188 | * @return bool 189 | * @throws DbException 190 | */ 191 | public function commit() 192 | { 193 | try { 194 | $result = $this->getConnection()->commit(); 195 | } catch (\PDOException $e) { 196 | throw new DbException($e->getMessage(), (int) $e->getCode(), $e); 197 | } 198 | return $result; 199 | } 200 | 201 | /** 202 | * Launch non-SELECT query 203 | * 204 | * @param string $sql Non-SELECT SQL-query 205 | * @param array $params Query values 206 | * @param string|null $types Placeholders types 207 | * 208 | * @return bool 209 | */ 210 | public function query($sql, array $params, $types) 211 | { 212 | $result = false; 213 | 214 | try { 215 | if (empty($params)) { 216 | return (bool)$this->getConnection()->query($sql); 217 | } 218 | 219 | $this->stmt = $this->getConnection()->prepare($sql); 220 | 221 | if (null === $types) { 222 | $result = $this->stmt->execute($params); 223 | } else { 224 | $this->bindParams($params, $types); 225 | $result = $this->stmt->execute(); 226 | } 227 | } catch (\PDOException $e) { 228 | $this->throwExceptionWithInfo($sql, $params, $e); 229 | } 230 | 231 | return $result; 232 | } 233 | 234 | /** 235 | * Get last saved ID 236 | * 237 | * @return int 238 | * @throws DbException 239 | */ 240 | public function getLastInsertId() 241 | { 242 | try { 243 | $result = (int) $this->getConnection()->lastInsertId(); 244 | } catch (\PDOException $e) { 245 | throw new DbException($e->getMessage(), (int) $e->getCode(), $e); 246 | } 247 | return $result; 248 | } 249 | 250 | /** 251 | * Get found rows quantity 252 | * 253 | * @return int 254 | * @throws DbException 255 | */ 256 | public function getFoundRows() 257 | { 258 | return (int) $this->value('SELECT FOUND_ROWS()', [], null); 259 | } 260 | 261 | /** 262 | * Get PDOStatement 263 | * 264 | * Used in subscribers for getting error information 265 | * 266 | * @return mixed 267 | */ 268 | public function getStmt() 269 | { 270 | return $this->stmt; 271 | } 272 | 273 | /** 274 | * Escape variable 275 | * 276 | * @param string $var 277 | * 278 | * @return string 279 | * @throws DbException 280 | */ 281 | public function escape($var) 282 | { 283 | try { 284 | $result = $this->getConnection()->quote($var); 285 | } catch (\PDOException $e) { 286 | throw new DbException($e->getMessage(), (int) $e->getCode(), $e); 287 | } 288 | return $result; 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /lib/DataBase/Adapters/iDbAdapter.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date 2013-12-31 15:44 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase\Adapters; 17 | 18 | /** 19 | * Interface iDbAdapter 20 | * 21 | * Db adapters interface 22 | * 23 | * @author Alexander Yancharuk 24 | */ 25 | interface iDbAdapter 26 | { 27 | /** 28 | * Get value from table row 29 | * 30 | * @param string $sql SQL-query 31 | * @param array $params Query values 32 | * @param string|null $types Placeholders types 33 | * @return string 34 | */ 35 | public function value($sql, array $params, $types); 36 | 37 | /** 38 | * Get table row 39 | * 40 | * @param string $sql SQL-query 41 | * @param array $params Query values 42 | * @param string|null $types Placeholders types 43 | * @return array 44 | */ 45 | public function row($sql, array $params, $types); 46 | 47 | /** 48 | * Get result collection 49 | * 50 | * @param string $sql SQL-query 51 | * @param array $params Query values 52 | * @param string|null $types Placeholders types 53 | * @return mixed 54 | */ 55 | public function rows($sql, array $params, $types); 56 | 57 | /** 58 | * Transaction initialization 59 | * 60 | * @return bool 61 | */ 62 | public function begin(); 63 | 64 | /** 65 | * Transaction rollback 66 | * 67 | * @return bool 68 | */ 69 | public function rollback(); 70 | 71 | /** 72 | * Commit transaction 73 | * 74 | * @return bool 75 | */ 76 | public function commit(); 77 | 78 | /** 79 | * Launch non-SELECT query 80 | * 81 | * @param string $sql Non-SELECT SQL-query 82 | * @param array $params Query values 83 | * @param string|null $types Placeholders types 84 | * @return bool 85 | */ 86 | public function query($sql, array $params, $types); 87 | 88 | /** 89 | * Get last saved ID 90 | * 91 | * @return int 92 | */ 93 | public function getLastInsertId(); 94 | 95 | /** 96 | * Get found rows quantity 97 | * 98 | * @return int 99 | */ 100 | public function getFoundRows(); 101 | 102 | /** 103 | * Get PDOStatement 104 | * 105 | * Used in subscribers for getting error information 106 | * 107 | * @return mixed 108 | */ 109 | public function getStmt(); 110 | 111 | /** 112 | * Escape variable 113 | * 114 | * @param string $var 115 | * @return string 116 | */ 117 | public function escape($var); 118 | } 119 | -------------------------------------------------------------------------------- /lib/DataBase/ConnectionPools/ConnectionPool.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date 2013-12-31 15:44 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase\ConnectionPools; 17 | 18 | use DataBase\Connections\PdoConnection; 19 | 20 | /** 21 | * Class ConnectionPool 22 | * 23 | * @author Alexander Yancharuk 24 | */ 25 | class ConnectionPool 26 | { 27 | /** @var array */ 28 | protected $pool; 29 | /** @var string */ 30 | protected $conn_name; 31 | 32 | /** 33 | * @return string 34 | */ 35 | public function getDefaultConnectionName() 36 | { 37 | return $this->conn_name; 38 | } 39 | 40 | /** 41 | * Add connection to connection pool 42 | * 43 | * @param PdoConnection $conn 44 | * @param bool $default Flag is this connection default or not 45 | * @return $this 46 | * @see DbConnection 47 | */ 48 | public function addConnection(PdoConnection $conn, $default = false) 49 | { 50 | $this->pool[$conn->getName()] = $conn; 51 | 52 | if ($default) { 53 | $this->conn_name = $conn->getName(); 54 | } 55 | return $this; 56 | } 57 | 58 | /** 59 | * Get connection class by name 60 | * 61 | * @param string $name Connection name 62 | * @return PdoConnection|null 63 | * @see DbConnection 64 | */ 65 | public function getConnection($name) 66 | { 67 | return isset($this->pool[$name]) ? $this->pool[$name] : null; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/DataBase/Connections/DbConnection.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date 2013-12-31 15:44 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase\Connections; 17 | 18 | use Exception; 19 | 20 | /** 21 | * Class DbConnection 22 | * 23 | * Базовый класс-контейнер для хранения общих для всех соединений параметров 24 | * 25 | * @author Alexander Yancharuk 26 | */ 27 | abstract class DbConnection 28 | { 29 | /** @var string */ 30 | protected $user_name; 31 | /** @var string */ 32 | protected $password; 33 | /** @var string */ 34 | protected $name; 35 | /** @var mixed */ 36 | protected $resource; 37 | 38 | /** 39 | * @param string $name Unique connection name 40 | */ 41 | public function __construct($name) 42 | { 43 | $this->name = $name; 44 | } 45 | 46 | /** 47 | * Connection create 48 | * 49 | * Must be realized in child classes 50 | * 51 | * @return mixed 52 | */ 53 | abstract public function create(); 54 | 55 | /** 56 | * @return mixed 57 | */ 58 | public function getResource() 59 | { 60 | return $this->resource; 61 | } 62 | 63 | /** 64 | * @param mixed $resource 65 | */ 66 | public function setResource($resource) 67 | { 68 | $this->resource = $resource; 69 | } 70 | 71 | /** 72 | * @return string 73 | */ 74 | public function getName() 75 | { 76 | return $this->name; 77 | } 78 | 79 | /** 80 | * @throws Exception 81 | * @return string 82 | */ 83 | public function getPassword() 84 | { 85 | return $this->password; 86 | } 87 | 88 | /** 89 | * @param string $password 90 | * @return $this 91 | */ 92 | public function setPassword($password) 93 | { 94 | $this->password = $password; 95 | return $this; 96 | } 97 | 98 | /** 99 | * @throws Exception 100 | * @return string 101 | */ 102 | public function getUserName() 103 | { 104 | return $this->user_name; 105 | } 106 | 107 | /** 108 | * @param string $user_name 109 | * @return $this 110 | */ 111 | public function setUserName($user_name) 112 | { 113 | $this->user_name = $user_name; 114 | return $this; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /lib/DataBase/Connections/PdoConnection.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date 2013-12-31 15:44 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase\Connections; 17 | 18 | use Exception; 19 | use PDO; 20 | 21 | /** 22 | * Class PdoConnection 23 | * 24 | * Class-container for PDO connection and it's options 25 | * 26 | * @author Alexander Yancharuk 27 | */ 28 | class PdoConnection extends DbConnection 29 | { 30 | /** @var string */ 31 | protected $dsn; 32 | /** @var array */ 33 | protected $options; 34 | /** @var array */ 35 | protected $callbacks = []; 36 | 37 | /** 38 | * Create connection 39 | * 40 | * @return \PDO 41 | */ 42 | public function create() 43 | { 44 | $this->resource = new PDO( 45 | $this->getDsn(), $this->getUserName(), 46 | $this->getPassword(), $this->getOptions() 47 | ); 48 | 49 | if ([] === $this->callbacks) { 50 | return $this->resource; 51 | } 52 | 53 | foreach ($this->callbacks as $call) { 54 | call_user_func_array( 55 | [$this->resource, $call['method']], $call['arguments'] 56 | ); 57 | } 58 | 59 | return $this->resource; 60 | } 61 | 62 | /** 63 | * Set connection DSN (Data Source Name) 64 | * 65 | * @param string $dsn 66 | * 67 | * @return $this 68 | */ 69 | public function setDsn($dsn) 70 | { 71 | $this->dsn = $dsn; 72 | return $this; 73 | } 74 | 75 | /** 76 | * Get connection DSN (Data Source Name) 77 | * 78 | * @throws Exception 79 | * 80 | * @return string 81 | */ 82 | public function getDsn() 83 | { 84 | if (null === $this->dsn) { 85 | throw new Exception('Connection DSN not set.'); 86 | } 87 | return $this->dsn; 88 | } 89 | 90 | /** 91 | * Set connection options 92 | * 93 | * @param array $options 94 | * 95 | * @return $this 96 | */ 97 | public function setOptions(array $options) 98 | { 99 | $this->options = $options; 100 | return $this; 101 | } 102 | 103 | /** 104 | * Get connection options 105 | * 106 | * @throws Exception 107 | * 108 | * @return array 109 | */ 110 | public function getOptions() 111 | { 112 | return $this->options; 113 | } 114 | 115 | /** 116 | * Get connection callbacks 117 | * 118 | * @return array 119 | */ 120 | public function getCallbacks() 121 | { 122 | return $this->callbacks; 123 | } 124 | 125 | /** 126 | * Save calls for future invocation 127 | * 128 | * @param string $method Method name that should be called 129 | * @param array $arguments Method arguments 130 | * 131 | * @return $this 132 | */ 133 | public function setCallback($method, array $arguments) 134 | { 135 | $this->callbacks[] = [ 136 | 'method' => $method, 137 | 'arguments' => $arguments 138 | ]; 139 | return $this; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /lib/DataBase/Db.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date Thu May 2 11:51:05 2013 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase; 17 | 18 | /** 19 | * Class Db 20 | * 21 | * Класс с методами обработки и вызова запросов 22 | * Типы плейсхолдеров указываются в mysqli-формате: 23 | * i - integer 24 | * d - float/double 25 | * s - string 26 | * b - binary 27 | * Если для плейсходеров не указываются типы, используется тип string 28 | * 29 | * @author Alexander Yancharuk 30 | */ 31 | class Db extends DbTransactionHandler 32 | { 33 | /** 34 | * Получение значения столбца таблицы 35 | * 36 | * @param string $sql SQL-запрос 37 | * @param array $params Плейсхолдеры запроса 38 | * @param string|null $types Типы плейсхолдеров 39 | * 40 | * @return mixed Returns string or false on failure or empty result 41 | */ 42 | public static function value($sql, array $params = [], $types = null) 43 | { 44 | return self::getAdapter()->value($sql, $params, $types); 45 | } 46 | 47 | /** 48 | * Получение строки таблицы в виде ассоциативного массива 49 | * 50 | * @param string $sql SQL-запрос 51 | * @param array $params Плейсхолдеры запроса 52 | * @param string|null $types Типы плейсхолдеров 53 | * 54 | * @return mixed Returns array or false on failure or empty result 55 | */ 56 | public static function row($sql, array $params = [], $types = null) 57 | { 58 | return self::getAdapter()->row($sql, $params, $types); 59 | } 60 | 61 | /** 62 | * Получение результата в виде коллекции ассоциативных массивов 63 | * 64 | * @param string $sql SQL-запрос 65 | * @param array $params Плейсхолдеры запроса 66 | * @param string|null $types Типы плейсхолдеров 67 | * 68 | * @return mixed Returns array or false on failure 69 | */ 70 | public static function rows($sql, array $params = [], $types = null) 71 | { 72 | return self::getAdapter()->rows($sql, $params, $types); 73 | } 74 | 75 | /** 76 | * Запуск произвольного не SELECT запроса 77 | * 78 | * @param string $sql Non-SELECT SQL-запрос 79 | * @param array $params Плейсхолдеры запроса 80 | * @param string|null $types Типы плейсхолдеров 81 | * 82 | * @return bool 83 | */ 84 | public static function query($sql, array $params = [], $types = null) 85 | { 86 | return self::getAdapter()->query($sql, $params, $types); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /lib/DataBase/DbBase.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date Срд Апр 23 06:34:47 MSK 2014 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase; 17 | 18 | use Exception; 19 | use DataBase\Adapters\DbAdapterBase; 20 | use DataBase\Adapters\iDbAdapter; 21 | 22 | /** 23 | * Class DbBase 24 | * 25 | * Базовый класс для работы с базой данных 26 | * 27 | * @author Alexander Yancharuk 28 | */ 29 | class DbBase 30 | { 31 | /** @var iDbAdapter|DbAdapterBase */ 32 | protected static $adapter; 33 | /** @var mixed */ 34 | protected static $connection; 35 | /** @var string */ 36 | protected static $connection_name; 37 | 38 | /** 39 | * Сохраняем имя класса адаптера для последующей инициализации 40 | * Будет инициализирован при первом запросе данных из базы 41 | * 42 | * @param iDbAdapter $adapter Adapter 43 | * @see Db::getAdapter 44 | */ 45 | public static function setAdapter(iDbAdapter $adapter) 46 | { 47 | self::$adapter = $adapter; 48 | } 49 | 50 | /** 51 | * Инстанс адаптера 52 | * 53 | * @throws Exception 54 | * @return iDbAdapter|DbAdapterBase 55 | */ 56 | public static function getAdapter() 57 | { 58 | if (null === self::$adapter) { 59 | throw new Exception('Adapter not set!'); 60 | } 61 | 62 | return self::$adapter; 63 | } 64 | 65 | /** 66 | * Выбор соединения 67 | * 68 | * @param string $name Имя соединения 69 | * @return DbAdapterBase 70 | */ 71 | public static function connection($name) 72 | { 73 | return self::getAdapter()->setConnection($name); 74 | } 75 | 76 | /** 77 | * Получение последнего сохранённого ID 78 | * 79 | * @return int 80 | */ 81 | public static function getLastInsertId() 82 | { 83 | return self::getAdapter()->getLastInsertId(); 84 | } 85 | 86 | /** 87 | * Получение кол-ва строк в результате 88 | * 89 | * @return int 90 | */ 91 | public static function getFoundRows() 92 | { 93 | return self::getAdapter()->getFoundRows(); 94 | } 95 | 96 | /** 97 | * Escaping variable 98 | * 99 | * @param string $var 100 | * @return string 101 | */ 102 | public static function escape($var) 103 | { 104 | return self::getAdapter()->escape($var); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /lib/DataBase/DbFilter.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date Втр Авг 07 23:14:17 2012 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase; 17 | 18 | /** 19 | * Класс DbFilter 20 | * @author Alexander Yancharuk 21 | */ 22 | class DbFilter 23 | { 24 | protected $where = ''; 25 | protected $group = ''; 26 | protected $having = ''; 27 | protected $order = ''; 28 | 29 | /** 30 | * Метод для получения where 31 | * @return string 32 | */ 33 | public function getWhere() 34 | { 35 | return $this->where; 36 | } 37 | 38 | /** 39 | * Метод для получения group by 40 | * @return string 41 | */ 42 | public function getGroup() 43 | { 44 | return $this->group; 45 | } 46 | 47 | /** 48 | * Метод для получения having 49 | * @return string 50 | */ 51 | public function getHaving() 52 | { 53 | return $this->having; 54 | } 55 | 56 | /** 57 | * Метод для получения order by 58 | * @return string 59 | */ 60 | public function getOrder() 61 | { 62 | return $this->order; 63 | } 64 | 65 | /** 66 | * Метод для установки значения where 67 | * @param string $where WHERE для sql-запроса 68 | */ 69 | public function setWhere($where) 70 | { 71 | $this->where = "WHERE $where"; 72 | } 73 | 74 | /** 75 | * Метод для установки значения group by 76 | * @param string $group GROUP BY для sql-запроса 77 | */ 78 | public function setGroup($group) 79 | { 80 | $this->group = "GROUP BY $group"; 81 | } 82 | 83 | /** 84 | * Метод для установки значения having 85 | * @param string $having HAVING для sql-запроса 86 | */ 87 | public function setHaving($having) 88 | { 89 | $this->having = "HAVING $having"; 90 | } 91 | 92 | /** 93 | * Метод для установки значения order by 94 | * @param string $order ORDER BY для sql-запроса 95 | */ 96 | public function setOrder($order) 97 | { 98 | $this->order = "ORDER BY $order"; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /lib/DataBase/DbPaginator.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date Втр Авг 07 23:04:47 2012 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase; 17 | 18 | use stdClass; 19 | use Tools\SnippetBuilder; 20 | 21 | /** 22 | * Class DbPaginator 23 | * 24 | * Additional data for rendering can be stored as public params. 25 | * For this purpose class extends stdClass. 26 | * 27 | * @author Alexander Yancharuk 28 | */ 29 | class DbPaginator extends stdClass 30 | { 31 | public $offset = 1; 32 | public $limit = 5; 33 | public $page_nums; 34 | public $curr_page; 35 | public $template; 36 | 37 | /** 38 | * Constructor 39 | * @param string $template Path to template 40 | * @param int $curr_page Current page 41 | */ 42 | public function __construct($template, $curr_page = 1) 43 | { 44 | $this->template = $template; 45 | $this->curr_page = (int) $curr_page; 46 | } 47 | 48 | /** 49 | * Pagination rendering 50 | */ 51 | public function __toString() 52 | { 53 | $this->first_link = false; 54 | $this->last_link = false; 55 | $this->index = 1; 56 | 57 | if ($this->curr_page > 4) { 58 | $this->first_link = 1; 59 | $this->index = $this->curr_page - 3; 60 | } 61 | 62 | if ($this->page_nums > $this->curr_page + 3) { 63 | $this->last_link = $this->page_nums; 64 | $this->page_nums = $this->curr_page + 3; 65 | } 66 | 67 | $builder = new SnippetBuilder($this); 68 | 69 | return $builder->build($this->template); 70 | } 71 | 72 | /** 73 | * Getting offset 74 | * @return int 75 | */ 76 | public function getOffset() 77 | { 78 | return ($this->curr_page - 1) * $this->getLimit(); 79 | } 80 | 81 | /** 82 | * Getting limit 83 | * @return int 84 | */ 85 | public function getLimit() 86 | { 87 | return $this->limit; 88 | } 89 | 90 | /** 91 | * Elements per page setting 92 | * @param int $limit Кол-во выводимых элементов на странице 93 | */ 94 | public function setLimit($limit) 95 | { 96 | if (!is_numeric($limit)) { 97 | return; 98 | } 99 | 100 | $this->limit = (int) $limit; 101 | } 102 | 103 | /** 104 | * Getting limit for sql-request 105 | * @return string 106 | */ 107 | public function getSqlLimit() 108 | { 109 | $offset = $this->getOffset(); 110 | $limit = $this->getLimit(); 111 | return " LIMIT $offset, $limit"; 112 | } 113 | 114 | /** 115 | * Pages quantity 116 | */ 117 | public function getMaxPages() 118 | { 119 | if (null !== $this->page_nums) { 120 | return $this->page_nums; 121 | } 122 | 123 | $this->calcMaxPages(); 124 | 125 | return $this->page_nums; 126 | } 127 | 128 | /** 129 | * Pages quantity calculation 130 | */ 131 | public function calcMaxPages() 132 | { 133 | $this->page_nums = (int) ceil(Db::getFoundRows() / $this->getLimit()); 134 | } 135 | 136 | /** 137 | * Getting current page 138 | */ 139 | public function getCurrPage() 140 | { 141 | return $this->curr_page; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /lib/DataBase/DbTransactionHandler.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date Срд Апр 23 06:34:47 MSK 2014 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase; 17 | 18 | /** 19 | * Class DbTransactionHandler 20 | * 21 | * Класс, содержащий функционал транзакций 22 | * 23 | * @author Alexander Yancharuk 24 | */ 25 | class DbTransactionHandler extends DbBase 26 | { 27 | /** 28 | * Инициализация транзакции 29 | * 30 | * @return bool 31 | */ 32 | public static function begin() 33 | { 34 | return self::getAdapter()->begin(); 35 | } 36 | 37 | /** 38 | * Откат транзакции 39 | * 40 | * @return bool 41 | */ 42 | public static function rollback() 43 | { 44 | return self::getAdapter()->rollback(); 45 | } 46 | 47 | /** 48 | * Сохранение всех запросов транзакции и её закрытие 49 | * 50 | * @return bool 51 | */ 52 | public static function commit() 53 | { 54 | return self::getAdapter()->commit(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/DataBase/Exceptions/DbException.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date Птн Мар 09 01:40:46 2012 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase\Exceptions; 17 | 18 | use Exception; 19 | 20 | /** 21 | * General db exception class 22 | * 23 | * @author Alexander Yancharuk 24 | */ 25 | class DbException extends Exception 26 | { 27 | protected $ansi_code; 28 | /** @var string */ 29 | protected $sql = ''; 30 | /** @var array */ 31 | protected $params = []; 32 | 33 | public function __construct($msg, $code, $exception) 34 | { 35 | parent::__construct($msg, $code, $exception); 36 | 37 | if ($exception instanceof \PDOException) { 38 | $pattern1 = '/SQLSTATE\[(.+)\]:[\s\w]+: ([\w\d]+) ([\s\S]+)$/'; 39 | $pattern2 = '/SQLSTATE\[(.+)\] \[([\w\d]+)\] ([\s\S]+)/'; 40 | 41 | preg_match($pattern1, $exception->getMessage(), $match) 42 | || preg_match($pattern2, $exception->getMessage(), $match); 43 | 44 | $this->setAnsiCode($match[1]); 45 | $this->code = (int) $match[2]; 46 | $this->message = $match[3]; 47 | } 48 | } 49 | 50 | /** 51 | * @return mixed 52 | */ 53 | public function getAnsiCode() 54 | { 55 | return $this->ansi_code; 56 | } 57 | 58 | /** 59 | * @param mixed $ansi_code 60 | */ 61 | public function setAnsiCode($ansi_code) 62 | { 63 | $this->ansi_code = $ansi_code; 64 | } 65 | 66 | /** 67 | * @return string 68 | */ 69 | public function getSql() 70 | { 71 | return $this->sql; 72 | } 73 | 74 | /** 75 | * @param string $sql 76 | */ 77 | public function setSql($sql) 78 | { 79 | $this->sql = $sql; 80 | } 81 | 82 | /** 83 | * @return array 84 | */ 85 | public function getParams() 86 | { 87 | return $this->params; 88 | } 89 | 90 | /** 91 | * @param array $params 92 | */ 93 | public function setParams(array $params) 94 | { 95 | $this->params = $params; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /lib/DataBase/Loggers/PdoErrorLogger.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright © 2012-2019 Alexander Yancharuk 11 | * @date 2013-12-31 15:44 12 | * @license The BSD 3-Clause License 13 | * 14 | */ 15 | 16 | namespace DataBase\Loggers; 17 | 18 | use SplSubject; 19 | 20 | /** 21 | * Class PdoErrorLogger 22 | * 23 | * Класс-подписчик PDO-адаптера. Предназначен для логгирования ошибок 24 | * 25 | * @author Alexander Yancharuk 26 | */ 27 | class PdoErrorLogger implements \SplObserver 28 | { 29 | /** @var string */ 30 | private $path; 31 | 32 | /** 33 | * Установка пути к логу 34 | * 35 | * @param string $path Путь к логу 36 | */ 37 | public function setPath($path) 38 | { 39 | $this->path = $path; 40 | } 41 | 42 | /** 43 | * Получение пути к логу 44 | * 45 | * @return string 46 | */ 47 | public function getPath() 48 | { 49 | return $this->path; 50 | } 51 | 52 | /** 53 | * Получение обновления 54 | * 55 | * @param SplSubject $subject 56 | */ 57 | public function update(SplSubject $subject) 58 | { 59 | /** @noinspection PhpUndefinedMethodInspection */ 60 | /** @var \PDO $conn */ 61 | $conn = $subject->getConnection(); 62 | /** @noinspection PhpUndefinedMethodInspection */ 63 | $conn_err = $conn->errorCode(); 64 | /** @noinspection PhpUndefinedMethodInspection */ 65 | /** @var \PdoStatement $stmt */ 66 | $stmt = $subject->getStmt(); 67 | /** @noinspection PhpUndefinedMethodInspection */ 68 | $stmt_err = $stmt->errorCode(); 69 | 70 | if ('00000' === $conn_err && '00000' === $stmt_err) 71 | return; 72 | 73 | $error_info = ('00000' === $conn_err) 74 | ? implode('; ', $stmt->errorInfo()) . PHP_EOL 75 | : implode('; ', $conn->errorInfo()) . PHP_EOL; 76 | 77 | error_log($error_info, 3, $this->getPath()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/NotPhar/ClassEight.php: -------------------------------------------------------------------------------- 1 | 13 | * 14 | * @file test 15 | * 16 | * PHP version 5.4+ 17 | * 18 | * @author Yancharuk Alexander 19 | * @date Сбт Фев 16 17:01:16 2013 20 | * @license The BSD 3-Clause License. 21 | * 22 | */ 23 | 24 | use Veles\AutoLoader; 25 | use Veles\DataBase\ConnectionPools\ConnectionPool; 26 | use Veles\DataBase\Connections\PdoConnection; 27 | use Veles\DataBase\Adapters\PdoAdapter; 28 | use Veles\DataBase\Db; 29 | 30 | define('BASE_PATH', realpath(__DIR__)); 31 | 32 | setlocale(LC_ALL, 'ru_RU.utf8'); 33 | date_default_timezone_set('Europe/Moscow'); 34 | /** @noinspection PhpIncludeInspection */ 35 | require 'lib/Veles/AutoLoader.php'; 36 | 37 | set_include_path( 38 | implode(PATH_SEPARATOR, [BASE_PATH . '/lib', get_include_path()]) 39 | ); 40 | 41 | AutoLoader::init(); 42 | 43 | // Db class initialization 44 | $pool = new ConnectionPool(); 45 | $conn = new PdoConnection('master'); 46 | 47 | $conn->setDsn('mysql:host=localhost;dbname=dbname;charset=utf8') 48 | ->setUserName('user') 49 | ->setPassword('password') 50 | ->setOptions([ 51 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 52 | PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 53 | PDO::ATTR_EMULATE_PREPARES => false 54 | ]); 55 | $pool->addConnection($conn, true); 56 | Db::setAdapter((new PdoAdapter)->setPool($pool)); 57 | 58 | if ($argc < 2) { 59 | throw new Exception('Enter class name as parameter!'); 60 | } 61 | 62 | $app_class = "Tests\\$argv[1]"; 63 | $application = new $app_class; 64 | $application->testDependencies(); 65 | $application->run(); 66 | $application->showResults(); 67 | -------------------------------------------------------------------------------- /test-list: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in $(ls Tests); do 4 | echo ${i%.*} 5 | done | column -x 6 | -------------------------------------------------------------------------------- /test-new: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 24 | * @file $file_name 25 | * 26 | * PHP version 5.6+ 27 | * 28 | * @author $user_name <$user_mail> 29 | * @copyright © 2013-$curr_year $user_name 30 | * @date $curr_date 31 | * @license $license 32 | * <$lic_link> 33 | */ 34 | 35 | namespace Tests; 36 | 37 | use Veles\Tools\CliProgressBar; 38 | use Veles\Tools\Timer; 39 | use Application\TestApplication; 40 | 41 | /** 42 | * Class $test_name 43 | * 44 | * @author $user_name <$user_mail> 45 | */ 46 | class $test_name extends TestApplication 47 | { 48 | protected \$repeats = 10000; 49 | 50 | public function run() 51 | { 52 | \$repeats = \$this->getRepeats(); 53 | EOT; 54 | 55 | $i = 0; 56 | while (++$i <= $test_cnt) { 57 | $content .= <<update(\$i); 67 | } 68 | 69 | \$this->addResult('ResultName$i', Timer::get()); 70 | EOT; 71 | } 72 | 73 | $content .= <<