Skip to content

Commit da852f1

Browse files
committed
Add basic benchmarks
1 parent e3b6462 commit da852f1

13 files changed

+713
-1
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.* export-ignore
22
*.md export-ignore
33
tests export-ignore
4+
benchmark export-ignore
45
docs export-ignore
56
examples export-ignore
67
mongo-orchestration export-ignore

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,8 @@ phpcs.xml
1515
# psalm
1616
psalm.xml
1717

18+
# phpbench
19+
.phpbench/
20+
phpbench.json
21+
1822
mongocryptd.pid

benchmark/BSON/DocumentBench.php

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
/*
3+
* Copyright 2023-present MongoDB, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace MongoDB\Benchmark\BSON;
19+
20+
use MongoDB\Benchmark\BaseBench;
21+
use MongoDB\BSON\Document;
22+
use PhpBench\Attributes\BeforeMethods;
23+
24+
use function file_get_contents;
25+
use function iterator_to_array;
26+
use function MongoDB\BSON\fromJSON;
27+
28+
#[BeforeMethods('prepareData')]
29+
final class DocumentBench extends BaseBench
30+
{
31+
private static string $rawBSON;
32+
private static Document $document;
33+
34+
public function prepareData(): void
35+
{
36+
self::$rawBSON = fromJSON(file_get_contents(self::LARGE_FILE_PATH));
37+
}
38+
39+
/** Create a document from the BSON string */
40+
public static function getBSONDocument(): Document
41+
{
42+
return self::$document ??= Document::fromBSON(self::$rawBSON);
43+
}
44+
45+
public function benchCheckFirst(): void
46+
{
47+
self::getBSONDocument()->has('qx3MigjubFSm');
48+
}
49+
50+
public function benchCheckLast(): void
51+
{
52+
self::getBSONDocument()->has('Zz2MOlCxDhLl');
53+
}
54+
55+
public function benchAccessFirst(): void
56+
{
57+
self::getBSONDocument()->get('qx3MigjubFSm');
58+
}
59+
60+
public function benchAccessLast(): void
61+
{
62+
self::getBSONDocument()->get('Zz2MOlCxDhLl');
63+
}
64+
65+
public function benchIteratorToArray(): void
66+
{
67+
iterator_to_array(self::getBSONDocument());
68+
}
69+
70+
public function benchToPHPObject(): void
71+
{
72+
self::getBSONDocument()->toPHP();
73+
}
74+
75+
public function benchToPHPArray(): void
76+
{
77+
self::getBSONDocument()->toPHP(['root' => 'array']);
78+
}
79+
80+
public function benchIteration(): void
81+
{
82+
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedForeach
83+
foreach (self::getBSONDocument() as $key => $value) {
84+
}
85+
}
86+
87+
public function benchIterationAsArray(): void
88+
{
89+
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedForeach
90+
foreach (self::getBSONDocument()->toPHP(['root' => 'array']) as $key => $value) {
91+
}
92+
}
93+
94+
public function benchIterationAsObject(): void
95+
{
96+
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedForeach
97+
foreach (self::getBSONDocument()->toPHP() as $key => $value) {
98+
}
99+
}
100+
}

benchmark/BSON/PackedArrayBench.php

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
/*
3+
* Copyright 2023-present MongoDB, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace MongoDB\Benchmark\BSON;
19+
20+
use MongoDB\Benchmark\BaseBench;
21+
use MongoDB\BSON\Document;
22+
use MongoDB\BSON\PackedArray;
23+
use PhpBench\Attributes\BeforeMethods;
24+
25+
use function array_values;
26+
use function file_get_contents;
27+
use function iterator_to_array;
28+
use function json_decode;
29+
use function MongoDB\BSON\fromPHP;
30+
31+
use const JSON_THROW_ON_ERROR;
32+
33+
#[BeforeMethods('prepareData')]
34+
final class PackedArrayBench extends BaseBench
35+
{
36+
private static string $rawBSONDocument;
37+
private static PackedArray $array;
38+
39+
public function prepareData(): void
40+
{
41+
$array = array_values(json_decode(file_get_contents(self::LARGE_FILE_PATH), true, 512, JSON_THROW_ON_ERROR));
42+
43+
// Store BSON string for a document since we can't create packed arrays from BSON strings
44+
self::$rawBSONDocument = fromPHP(['array' => $array]);
45+
}
46+
47+
/** Create a document from the BSON string */
48+
public static function getBSONArray(): PackedArray
49+
{
50+
return self::$array ??= Document::fromBSON(self::$rawBSONDocument)->get('array');
51+
}
52+
53+
public function benchCheckFirst(): void
54+
{
55+
self::getBSONArray()->has(0);
56+
}
57+
58+
public function benchCheckLast(): void
59+
{
60+
self::getBSONArray()->has(94354);
61+
}
62+
63+
public function benchAccessFirst(): void
64+
{
65+
self::getBSONArray()->get(0);
66+
}
67+
68+
public function benchAccessLast(): void
69+
{
70+
self::getBSONArray()->get(94354);
71+
}
72+
73+
public function benchIteratorToArray(): void
74+
{
75+
iterator_to_array(self::getBSONArray());
76+
}
77+
78+
public function benchToPHPArray(): void
79+
{
80+
self::getBSONArray()->toPHP();
81+
}
82+
83+
public function benchIteration(): void
84+
{
85+
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedForeach
86+
foreach (self::getBSONArray() as $key => $value) {
87+
}
88+
}
89+
90+
public function benchIterationAfterIteratorToArray(): void
91+
{
92+
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedForeach
93+
foreach (iterator_to_array(self::getBSONArray()) as $key => $value) {
94+
}
95+
}
96+
97+
public function benchIterationAsArray(): void
98+
{
99+
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedForeach
100+
foreach (self::getBSONArray()->toPHP() as $key => $value) {
101+
}
102+
}
103+
}

benchmark/BaseBench.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace MongoDB\Benchmark;
4+
5+
use MongoDB\Client;
6+
use MongoDB\Collection;
7+
8+
use function getenv;
9+
10+
abstract class BaseBench
11+
{
12+
protected const LARGE_FILE_PATH = __DIR__ . '/data/large_doc.json';
13+
protected const TWEET_FILE_PATH = __DIR__ . '/data/tweet.json';
14+
15+
private static ?Collection $collection;
16+
17+
protected static function getCollection(): Collection
18+
{
19+
return self::$collection ??= self::createCollection();
20+
}
21+
22+
protected static function createClient(array $options = [], array $driverOptions = []): Client
23+
{
24+
return new Client(self::getUri(), $options, $driverOptions);
25+
}
26+
27+
public static function createCollection(): Collection
28+
{
29+
$client = self::createClient();
30+
31+
return $client->selectCollection(self::getDatabase(), 'perftest');
32+
}
33+
34+
protected static function getUri(): string
35+
{
36+
return getenv('MONGODB_URI') ?: 'mongodb://localhost:27017/';
37+
}
38+
39+
protected static function getDatabase(): string
40+
{
41+
return getenv('MONGODB_DATABASE') ?: 'phplib_test';
42+
}
43+
}

0 commit comments

Comments
 (0)