Skip to content

Commit 7d57b95

Browse files
committed
Add continuous benchmarking
1 parent b324c2b commit 7d57b95

File tree

5 files changed

+297
-2
lines changed

5 files changed

+297
-2
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ composer.phar
55
build
66
/xhprof_report.*
77
benchmark-result.json
8-
/coverage.xml
8+
/coverage.xml
9+
/phpbench-candidate.xml
10+
/phpbench-master.xml

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ matrix:
2929
script:
3030
- php -derror_reporting="E_ALL & ~E_DEPRECATED" ./vendor/bin/phpunit -v --configuration phpunit.xml --coverage-text --coverage-clover=coverage.xml
3131
- if [[ $(phpenv version-name) =~ 7.3 ]] ; then make test-coverage; else make test; fi
32-
- if [[ $(phpenv version-name) =~ 7.2 ]] ; then make lint; fi
32+
- if [[ $(phpenv version-name) =~ 7.2 ]] ; then make lint;make bench;make bench-master;make bench-compare; fi
3333

3434
after_script:
3535
- if [[ $(phpenv version-name) =~ 7.3 ]] ; then bash <(curl -s https://codecov.io/bash); fi

Makefile

+15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
PHPSTAN_VERSION ?= 0.11.15
2+
PHPBENCH_VERSION ?= 0.16.10
23

34
deps:
45
@git submodule init && git submodule update
@@ -15,3 +16,17 @@ test:
1516

1617
test-coverage:
1718
@php -derror_reporting="E_ALL & ~E_DEPRECATED" -dzend_extension=xdebug.so vendor/bin/phpunit --coverage-text --coverage-clover=coverage.xml
19+
20+
phpbench:
21+
@test -f ${HOME}/.cache/composer/phpbench-${PHPBENCH_VERSION}.phar || (mkdir -p ${HOME}/.cache/composer/ && wget https://github.com/phpbench/phpbench/releases/download/${PHPBENCH_VERSION}/phpbench.phar -O ${HOME}/.cache/composer/phpbench-${PHPBENCH_VERSION}.phar)
22+
23+
bench: phpbench
24+
@php $$HOME/.cache/composer/phpbench-${PHPBENCH_VERSION}.phar run benchmarks --tag=candidate --progress=none --bootstrap=vendor/autoload.php --revs=50 --iterations=5 --retry-threshold=3 --dump-file=phpbench-candidate.xml
25+
26+
bench-master: phpbench
27+
@git checkout --detach && git fetch origin '+refs/heads/master:refs/heads/master' && git checkout master -- ./src
28+
@composer install --dev --no-interaction --prefer-dist
29+
@php $$HOME/.cache/composer/phpbench-${PHPBENCH_VERSION}.phar run benchmarks --tag=master --progress=none --bootstrap=vendor/autoload.php --revs=50 --iterations=5 --retry-threshold=3 --dump-file=phpbench-master.xml
30+
31+
bench-compare: phpbench
32+
@php $$HOME/.cache/composer/phpbench-${PHPBENCH_VERSION}.phar report --file phpbench-master.xml --file phpbench-candidate.xml --report='generator: "table", cols: [ "set" ], compare: "tag", compare_fields: ["mean"], break: ["benchmark"]'

benchmarks/AjvSchemasBench.php

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<?php
2+
3+
4+
use Swaggest\JsonSchema\Context;
5+
use Swaggest\JsonSchema\InvalidValue;
6+
use Swaggest\JsonSchema\RemoteRef\Preloaded;
7+
use Swaggest\JsonSchema\Schema;
8+
9+
class AjvSchemasBench
10+
{
11+
private static $cases;
12+
13+
public function provide()
14+
{
15+
foreach (self::$cases as $name => $tmp) {
16+
yield $name => ['name' => $name];
17+
}
18+
}
19+
20+
/**
21+
* @ParamProviders({"provide"})
22+
*/
23+
public function benchSpec($params)
24+
{
25+
$case = self::$cases[$params['name']];
26+
27+
$actualValid = true;
28+
try {
29+
$options = $this->makeOptions(Schema::VERSION_DRAFT_07);
30+
$options->schemasCache = self::$schemas;
31+
32+
$schema = Schema::import($case['schema'], $options);
33+
34+
$options->validateOnly = true;
35+
$schema->in($case['data'], $options);
36+
} catch (InvalidValue $exception) {
37+
$actualValid = false;
38+
}
39+
40+
if ($actualValid !== $case['isValid']) {
41+
throw new Exception('Assertion failed');
42+
}
43+
}
44+
45+
/** @var \SplObjectStorage */
46+
private static $schemas;
47+
48+
protected function makeOptions($version)
49+
{
50+
$refProvider = static::getProvider();
51+
52+
$options = new Context();
53+
$options->setRemoteRefProvider($refProvider);
54+
$options->version = $version;
55+
$options->strictBase64Validation = true;
56+
57+
return $options;
58+
}
59+
60+
public static function getProvider()
61+
{
62+
static $refProvider = null;
63+
64+
if (null === $refProvider) {
65+
$refProvider = new Preloaded();
66+
$refProvider
67+
->setSchemaData(
68+
'http://localhost:1234/integer.json',
69+
json_decode(file_get_contents(__DIR__
70+
. '/../spec/JSON-Schema-Test-Suite/remotes/integer.json')))
71+
->setSchemaData(
72+
'http://localhost:1234/subSchemas.json',
73+
json_decode(file_get_contents(__DIR__
74+
. '/../spec/JSON-Schema-Test-Suite/remotes/subSchemas.json')))
75+
->setSchemaData(
76+
'http://localhost:1234/name.json',
77+
json_decode(file_get_contents(__DIR__
78+
. '/../spec/JSON-Schema-Test-Suite/remotes/name.json')))
79+
->setSchemaData(
80+
'http://localhost:1234/folder/folderInteger.json',
81+
json_decode(file_get_contents(__DIR__
82+
. '/../spec/JSON-Schema-Test-Suite/remotes/folder/folderInteger.json')));
83+
}
84+
85+
return $refProvider;
86+
}
87+
88+
private static function provider($path)
89+
{
90+
$testCases = array();
91+
92+
if ($handle = opendir($path)) {
93+
while (false !== ($entry = readdir($handle))) {
94+
if ($entry != "." && $entry != "..") {
95+
if ('.json' !== substr($entry, -5)) {
96+
continue;
97+
}
98+
$tests = json_decode(file_get_contents($path . '/' . $entry));
99+
100+
foreach ($tests as $test) {
101+
foreach ($test->tests as $c => $case) {
102+
$name = $entry . ' ' . $test->description . ': ' . $case->description . ' [' . $c . ']';
103+
if (!isset($test->schema)) {
104+
if (isset($test->schemas)) {
105+
foreach ($test->schemas as $i => $schema) {
106+
$testCases[$name . '_' . $i] = array(
107+
'schema' => $schema,
108+
'data' => $case->data,
109+
'isValid' => $case->valid,
110+
'name' => $name,
111+
);
112+
}
113+
}
114+
continue;
115+
}
116+
$testCases[$name] = array(
117+
'schema' => $test->schema,
118+
'data' => $case->data,
119+
'isValid' => $case->valid,
120+
'name' => $name,
121+
);
122+
}
123+
}
124+
}
125+
}
126+
closedir($handle);
127+
}
128+
129+
return $testCases;
130+
}
131+
132+
public static function init()
133+
{
134+
self::$cases = self::provider(__DIR__ . '/../spec/ajv/spec/tests/schemas');
135+
self::$schemas = new \SplObjectStorage();
136+
}
137+
}
138+
139+
AjvSchemasBench::init();

benchmarks/Draft7Bench.php

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<?php
2+
3+
4+
use Swaggest\JsonSchema\Context;
5+
use Swaggest\JsonSchema\InvalidValue;
6+
use Swaggest\JsonSchema\RemoteRef\Preloaded;
7+
use Swaggest\JsonSchema\Schema;
8+
9+
class Draft7Bench
10+
{
11+
private static $cases;
12+
13+
public function provide()
14+
{
15+
foreach (self::$cases as $name => $tmp) {
16+
yield $name => ['name' => $name];
17+
}
18+
}
19+
20+
/**
21+
* @ParamProviders({"provide"})
22+
*/
23+
public function benchSpec($params)
24+
{
25+
$case = self::$cases[$params['name']];
26+
27+
$actualValid = true;
28+
try {
29+
$options = $this->makeOptions(Schema::VERSION_DRAFT_07);
30+
$options->schemasCache = self::$schemas;
31+
32+
$schema = Schema::import($case['schema'], $options);
33+
34+
$options->validateOnly = true;
35+
$schema->in($case['data'], $options);
36+
} catch (InvalidValue $exception) {
37+
$actualValid = false;
38+
}
39+
40+
if ($actualValid !== $case['isValid']) {
41+
throw new Exception('Assertion failed');
42+
}
43+
}
44+
45+
/** @var \SplObjectStorage */
46+
private static $schemas;
47+
48+
protected function makeOptions($version)
49+
{
50+
$refProvider = static::getProvider();
51+
52+
$options = new Context();
53+
$options->setRemoteRefProvider($refProvider);
54+
$options->version = $version;
55+
$options->strictBase64Validation = true;
56+
57+
return $options;
58+
}
59+
60+
public static function getProvider()
61+
{
62+
static $refProvider = null;
63+
64+
if (null === $refProvider) {
65+
$refProvider = new Preloaded();
66+
$refProvider
67+
->setSchemaData(
68+
'http://localhost:1234/integer.json',
69+
json_decode(file_get_contents(__DIR__
70+
. '/../spec/JSON-Schema-Test-Suite/remotes/integer.json')))
71+
->setSchemaData(
72+
'http://localhost:1234/subSchemas.json',
73+
json_decode(file_get_contents(__DIR__
74+
. '/../spec/JSON-Schema-Test-Suite/remotes/subSchemas.json')))
75+
->setSchemaData(
76+
'http://localhost:1234/name.json',
77+
json_decode(file_get_contents(__DIR__
78+
. '/../spec/JSON-Schema-Test-Suite/remotes/name.json')))
79+
->setSchemaData(
80+
'http://localhost:1234/folder/folderInteger.json',
81+
json_decode(file_get_contents(__DIR__
82+
. '/../spec/JSON-Schema-Test-Suite/remotes/folder/folderInteger.json')));
83+
}
84+
85+
return $refProvider;
86+
}
87+
88+
private static function provider($path)
89+
{
90+
$testCases = array();
91+
92+
if ($handle = opendir($path)) {
93+
while (false !== ($entry = readdir($handle))) {
94+
if ($entry != "." && $entry != "..") {
95+
if ('.json' !== substr($entry, -5)) {
96+
continue;
97+
}
98+
$tests = json_decode(file_get_contents($path . '/' . $entry));
99+
100+
foreach ($tests as $test) {
101+
foreach ($test->tests as $c => $case) {
102+
$name = $entry . ' ' . $test->description . ': ' . $case->description . ' [' . $c . ']';
103+
if (!isset($test->schema)) {
104+
if (isset($test->schemas)) {
105+
foreach ($test->schemas as $i => $schema) {
106+
$testCases[$name . '_' . $i] = array(
107+
'schema' => $schema,
108+
'data' => $case->data,
109+
'isValid' => $case->valid,
110+
'name' => $name,
111+
);
112+
}
113+
}
114+
continue;
115+
}
116+
$testCases[$name] = array(
117+
'schema' => $test->schema,
118+
'data' => $case->data,
119+
'isValid' => $case->valid,
120+
'name' => $name,
121+
);
122+
}
123+
}
124+
}
125+
}
126+
closedir($handle);
127+
}
128+
129+
return $testCases;
130+
}
131+
132+
public static function init()
133+
{
134+
self::$cases = self::provider(__DIR__ . '/../spec/JSON-Schema-Test-Suite/tests/draft7');
135+
self::$schemas = new \SplObjectStorage();
136+
}
137+
}
138+
139+
Draft7Bench::init();

0 commit comments

Comments
 (0)