Skip to content

Commit abdc73b

Browse files
committed
Introduce phpbench benchmarks and profiles
This commit is the first step in setting up *Continuous Performance* for the repository. - Adds phpbench/phpbench to dev dependencies. - Adds an initial `ValidatorBench.php` file with validate benchmarks for several validators. - Adds `composer bench` script to run benchmarks. - Adds `composer bench:profile` script to generate profiles.
1 parent cd96d01 commit abdc73b

4 files changed

Lines changed: 124 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
.couscous/
22
.iso-codes-cache/
3+
.phpbench/
34
.phpcs.cache
45
.phpunit.cache/
56
composer.lock
67
Makefile
8+
phpbench.json
79
phpcs.xml
810
phpstan.neon
911
phpunit.xml

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"mikey179/vfsstream": "^1.6",
3434
"nette/php-generator": "^4.1",
3535
"pestphp/pest": "^4.2",
36+
"phpbench/phpbench": "^1.4",
3637
"phpstan/extension-installer": "^1.4",
3738
"phpstan/phpstan": "^2.0",
3839
"phpstan/phpstan-deprecation-rules": "^2.0",
@@ -76,6 +77,8 @@
7677
"phpstan": "vendor/bin/phpstan analyze",
7778
"phpunit": "vendor/bin/phpunit --testsuite=unit",
7879
"pest": "vendor/bin/pest --testsuite=feature --compact",
80+
"bench": "vendor/bin/phpbench run",
81+
"bench:profile": "vendor/bin/phpbench xdebug:profile",
7982
"qa": [
8083
"@docheader",
8184
"@phpcs",

phpbench.json.dist

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"$schema": "./vendor/phpbench/phpbench/phpbench.schema.json",
3+
"runner.bootstrap": "vendor/autoload.php",
4+
"runner.path": "tests/benchmark",
5+
"runner.file_pattern": "*Bench.php"
6+
}

tests/benchmark/ValidatorBench.php

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Respect\Validation\Benchmarks;
6+
7+
/*
8+
* Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
9+
* SPDX-License-Identifier: MIT
10+
*/
11+
12+
use Generator;
13+
use PhpBench\Attributes as Bench;
14+
use Respect\Validation\Validator;
15+
use Respect\Validation\ValidatorBuilder as v;
16+
17+
class ValidatorBench
18+
{
19+
/** @param array<Validator, mixed> $params */ #[Bench\Iterations(10)]
20+
#[Bench\RetryThreshold(10)]
21+
#[Bench\Revs(5)]
22+
#[Bench\ParamProviders(['provideValidatorInput'])]
23+
public function benchValidate(array $params): void
24+
{
25+
[$v, $input] = $params;
26+
$v->validate($input);
27+
}
28+
29+
public function provideValidatorInput(): Generator
30+
{
31+
yield 'AllOf' => [v::allOf(v::intVal(), v::greaterThan(0)), 5];
32+
yield 'Alnum' => [v::alnum(), 'abc123'];
33+
yield 'Alpha' => [v::alpha(), 'abc'];
34+
yield 'AnyOf' => [v::anyOf(v::intVal(), v::stringVal()), 5];
35+
yield 'ArrayType' => [v::arrayType(), []];
36+
yield 'ArrayVal' => [v::arrayVal(), []];
37+
yield 'Between' => [v::between(1, 10), 5];
38+
yield 'BetweenExclusive' => [v::betweenExclusive(1, 10), 5];
39+
yield 'BoolType' => [v::boolType(), true];
40+
yield 'BoolVal' => [v::boolVal(), true];
41+
yield 'Bsn' => [v::bsn(), '612890053'];
42+
yield 'Call' => [v::call('array_keys', v::each(v::stringType())), ['a' => 'b']];
43+
yield 'Charset' => [v::charset('UTF-8'), 'example'];
44+
yield 'Circuit' => [v::circuit(v::intVal(), v::trueVal()), 123];
45+
yield 'Cnpj' => [v::cnpj(), '11444777000161'];
46+
yield 'Consonant' => [v::consonant(), 'bcdf'];
47+
yield 'Contains' => [v::contains('needle'), 'haystack needle'];
48+
yield 'ContainsAny' => [v::containsAny(['a', 'b']), 'abc'];
49+
yield 'Control' => [v::control(), "\n\r"];
50+
yield 'Countable' => [v::countable(), []];
51+
yield 'CountryCode' => [v::countryCode(), 'US'];
52+
yield 'Cpf' => [v::cpf(), '11598647644'];
53+
yield 'CurrencyCode' => [v::currencyCode(), 'USD'];
54+
yield 'Date' => [v::date(), '2020-01-01'];
55+
yield 'DateTime' => [v::dateTime(), '2020-01-01 12:00:00'];
56+
yield 'Decimal' => [v::decimal(2), '1.23'];
57+
yield 'Digit' => [v::digit(), '7'];
58+
yield 'Each' => [v::each(v::stringType()), ['a', 'b']];
59+
yield 'Email' => [v::email(), 'bob@example.com'];
60+
yield 'EndsWith' => [v::endsWith('.com'), 'example.com'];
61+
yield 'Equals' => [v::equals('x'), 'x'];
62+
yield 'Even' => [v::even(), 2];
63+
yield 'Executable' => [v::executable(), 'tests/fixtures/executable'];
64+
yield 'Exists' => [v::exists(), 'tests/fixtures/valid-image.png'];
65+
yield 'FalseVal' => [v::falseVal(), false];
66+
yield 'Fibonacci' => [v::fibonacci(), 13];
67+
yield 'File' => [v::file(), __FILE__];
68+
yield 'FloatType' => [v::floatType(), 1.23];
69+
yield 'FloatVal' => [v::floatVal(), 1.23];
70+
yield 'GreaterThan' => [v::greaterThan(0), 1];
71+
yield 'GreaterThanOrEqual' => [v::greaterThanOrEqual(1), 1];
72+
yield 'Hetu' => [v::hetu(), '010106A9012'];
73+
yield 'Iban' => [v::iban(), 'SE35 5000 0000 0549 1000 0003'];
74+
yield 'Identical' => [v::identical(123), 123];
75+
yield 'In' => [v::in(['a', 'b']), 'a'];
76+
yield 'IntType' => [v::intType(), 123];
77+
yield 'IntVal' => [v::intVal(), 123];
78+
yield 'Ip' => [v::ip(), '127.0.0.1'];
79+
yield 'IterableVal' => [v::iterableVal(), []];
80+
yield 'LanguageCode' => [v::languageCode(), 'en'];
81+
yield 'LessThan' => [v::lessThan(10), 5];
82+
yield 'LessThanOrEqual' => [v::lessThanOrEqual(10), 10];
83+
yield 'Lowercase' => [v::lowercase(), 'abc'];
84+
yield 'Luhn' => [v::luhn(), '2222400041240011'];
85+
yield 'MacAddress' => [v::macAddress(), '00:11:22:33:44:55'];
86+
yield 'Negative' => [v::negative(), -1];
87+
yield 'Nip' => [v::nip(), '1645865777'];
88+
yield 'Not' => [v::not(v::trueVal()), false];
89+
yield 'NullType' => [v::nullType(), null];
90+
yield 'NumericVal' => [v::numericVal(), '123'];
91+
yield 'Odd' => [v::odd(), 3];
92+
yield 'PerfectSquare' => [v::perfectSquare(), 16];
93+
yield 'Pesel' => [v::pesel(), '21120209256'];
94+
yield 'Property' => [v::property('email', v::endsWith('@example.com')), (object) ['email' => 'a@example.com']];
95+
yield 'PropertyExists' => [v::propertyExists('email'), (object) ['email' => 'a@example.com']];
96+
yield 'PropertyOptional' => [v::propertyOptional('missing', v::email()), (object) ['email' => 'a@example.com']];
97+
yield 'Readable' => [v::readable(), 'tests/fixtures/valid-image.png'];
98+
yield 'ScalarVal' => [v::scalarVal(), 'example'];
99+
yield 'Slug' => [v::slug(), 'a-valid-slug'];
100+
yield 'StartsWith' => [v::startsWith('ex'), 'example'];
101+
yield 'StringType' => [v::stringType(), 'example'];
102+
yield 'StringVal' => [v::stringVal(), 'example'];
103+
yield 'SymbolicLink' => [v::symbolicLink(), 'tests/fixtures/symbolic-link'];
104+
yield 'Time' => [v::time(), '12:34:56'];
105+
yield 'TrueVal' => [v::trueVal(), true];
106+
yield 'Unique' => [v::unique(), [1, 2, 3]];
107+
yield 'Uppercase' => [v::uppercase(), 'ABC'];
108+
yield 'Uuid' => [v::uuid(), '123e4567-e89b-12d3-a456-426655440000'];
109+
yield 'When' => [v::when(v::trueVal(), v::intVal()), 123];
110+
yield 'Writable' => [v::writable(), 'tests/fixtures/valid-image.png'];
111+
yield 'Xdigit' => [v::xdigit(), 'AF'];
112+
}
113+
}

0 commit comments

Comments
 (0)