Skip to content

Commit a7a7682

Browse files
authored
PHPLIB-1183: Add benchmarks for codecs (#1146)
* Move sample data to fixtures directory * Add benchmarks to test empty codec overhead * Add benchmark to convert BSON structures to PHP via iteration
1 parent 57a7f3b commit a7a7682

9 files changed

+146
-3
lines changed

benchmark/BSON/DocumentBench.php

+10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use MongoDB\Benchmark\BaseBench;
66
use MongoDB\BSON\Document;
77
use PhpBench\Attributes\BeforeMethods;
8+
use stdClass;
89

910
use function file_get_contents;
1011
use function iterator_to_array;
@@ -49,6 +50,15 @@ public function benchToPHPObject(): void
4950
self::$document->toPHP();
5051
}
5152

53+
public function benchToPHPObjectViaIteration(): void
54+
{
55+
$object = new stdClass();
56+
57+
foreach (self::$document as $key => $value) {
58+
$object->$key = $value;
59+
}
60+
}
61+
5262
public function benchToPHPArray(): void
5363
{
5464
self::$document->toPHP(['root' => 'array']);

benchmark/BSON/PackedArrayBench.php

+9
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ public function benchToPHPArray(): void
5555
self::$array->toPHP();
5656
}
5757

58+
public function benchToPHPArrayViaIteration(): void
59+
{
60+
$array = [];
61+
62+
foreach (self::$array as $key => $value) {
63+
$array[$key] = $value;
64+
}
65+
}
66+
5867
public function benchIteration(): void
5968
{
6069
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedForeach

benchmark/BaseBench.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99

1010
abstract class BaseBench
1111
{
12-
protected const LARGE_FILE_PATH = __DIR__ . '/data/large_doc.json';
13-
protected const TWEET_FILE_PATH = __DIR__ . '/data/tweet.json';
12+
protected const LARGE_FILE_PATH = __DIR__ . '/Fixtures/data/large_doc.json';
13+
protected const TWEET_FILE_PATH = __DIR__ . '/Fixtures/data/tweet.json';
1414

1515
private static ?Collection $collection;
1616

benchmark/Fixtures/PassThruCodec.php

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace MongoDB\Benchmark\Fixtures;
4+
5+
use MongoDB\BSON\Document;
6+
use MongoDB\Codec\DecodeIfSupported;
7+
use MongoDB\Codec\DocumentCodec;
8+
use MongoDB\Codec\EncodeIfSupported;
9+
use MongoDB\Exception\UnsupportedValueException;
10+
11+
final class PassThruCodec implements DocumentCodec
12+
{
13+
use DecodeIfSupported;
14+
use EncodeIfSupported;
15+
16+
/** @param mixed $value */
17+
public function canDecode($value): bool
18+
{
19+
return $value instanceof Document;
20+
}
21+
22+
/** @param mixed $value */
23+
public function canEncode($value): bool
24+
{
25+
return $value instanceof Document;
26+
}
27+
28+
/** @param mixed $value */
29+
public function decode($value): Document
30+
{
31+
if (! $value instanceof Document) {
32+
throw UnsupportedValueException::invalidDecodableValue($value);
33+
}
34+
35+
return $value;
36+
}
37+
38+
/** @param mixed $value */
39+
public function encode($value): Document
40+
{
41+
if (! $value instanceof Document) {
42+
throw UnsupportedValueException::invalidEncodableValue($value);
43+
}
44+
45+
return $value;
46+
}
47+
}

benchmark/Fixtures/ToObjectCodec.php

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace MongoDB\Benchmark\Fixtures;
4+
5+
use MongoDB\BSON\Document;
6+
use MongoDB\Codec\DecodeIfSupported;
7+
use MongoDB\Codec\DocumentCodec;
8+
use MongoDB\Codec\EncodeIfSupported;
9+
use MongoDB\Exception\UnsupportedValueException;
10+
11+
use function is_object;
12+
13+
final class ToObjectCodec implements DocumentCodec
14+
{
15+
use DecodeIfSupported;
16+
use EncodeIfSupported;
17+
18+
/** @param mixed $value */
19+
public function canDecode($value): bool
20+
{
21+
return $value instanceof Document;
22+
}
23+
24+
/** @param mixed $value */
25+
public function canEncode($value): bool
26+
{
27+
return is_object($value);
28+
}
29+
30+
/** @param mixed $value */
31+
public function decode($value): object
32+
{
33+
if (! $value instanceof Document) {
34+
throw UnsupportedValueException::invalidDecodableValue($value);
35+
}
36+
37+
return $value->toPHP(['root' => 'stdClass', 'array' => 'array', 'document' => 'stdClass']);
38+
}
39+
40+
/** @param mixed $value */
41+
public function encode($value): Document
42+
{
43+
if (! is_object($value)) {
44+
throw UnsupportedValueException::invalidEncodableValue($value);
45+
}
46+
47+
return Document::fromPHP($value);
48+
}
49+
}
File renamed without changes.
File renamed without changes.

benchmark/ReadLargeDocumentBench.php

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace MongoDB\Benchmark;
44

55
use Generator;
6+
use MongoDB\Benchmark\Fixtures\PassThruCodec;
7+
use MongoDB\Benchmark\Fixtures\ToObjectCodec;
68
use MongoDB\BSON\Document;
79
use MongoDB\Exception\InvalidArgumentException;
810
use MongoDB\Model\BSONArray;
@@ -40,7 +42,7 @@ public function provideParams(): Generator
4042
{
4143
yield 'Driver default typemap' => [
4244
'codec' => null,
43-
'typeMap' => [],
45+
'typeMap' => null,
4446
'accessor' => 'object',
4547
];
4648

@@ -65,6 +67,18 @@ public function provideParams(): Generator
6567
'typeMap' => ['root' => 'bson'],
6668
'accessor' => 'bson',
6769
];
70+
71+
yield 'Codec (pass thru)' => [
72+
'codec' => new PassThruCodec(),
73+
'typeMap' => null,
74+
'accessor' => 'bson',
75+
];
76+
77+
yield 'Codec (to object)' => [
78+
'codec' => new ToObjectCodec(),
79+
'typeMap' => null,
80+
'accessor' => 'object',
81+
];
6882
}
6983

7084
#[ParamProviders('provideParams')]

benchmark/ReadMultipleDocumentsBench.php

+14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace MongoDB\Benchmark;
44

55
use Generator;
6+
use MongoDB\Benchmark\Fixtures\PassThruCodec;
7+
use MongoDB\Benchmark\Fixtures\ToObjectCodec;
68
use MongoDB\BSON\Document;
79
use MongoDB\Exception\InvalidArgumentException;
810
use MongoDB\Model\BSONArray;
@@ -65,6 +67,18 @@ public function provideParams(): Generator
6567
'typeMap' => ['root' => 'bson'],
6668
'accessor' => 'bson',
6769
];
70+
71+
yield 'Codec (pass thru)' => [
72+
'codec' => new PassThruCodec(),
73+
'typeMap' => null,
74+
'accessor' => 'bson',
75+
];
76+
77+
yield 'Codec (to object)' => [
78+
'codec' => new ToObjectCodec(),
79+
'typeMap' => null,
80+
'accessor' => 'object',
81+
];
6882
}
6983

7084
#[ParamProviders('provideParams')]

0 commit comments

Comments
 (0)