Skip to content

Commit 12822d3

Browse files
committed
PHPLIB-1236 Implement GridFS Benchmarks
1 parent bc85f1e commit 12822d3

File tree

6 files changed

+116
-26
lines changed

6 files changed

+116
-26
lines changed

benchmark/DriverBench/GridFSBench.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace MongoDB\Benchmark\DriverBench;
4+
5+
use MongoDB\Benchmark\Fixtures\Data;
6+
use MongoDB\Benchmark\Utils;
7+
use MongoDB\GridFS\Bucket;
8+
use PhpBench\Attributes\AfterMethods;
9+
use PhpBench\Attributes\BeforeMethods;
10+
11+
/**
12+
* For accurate results, run benchmarks on a standalone server.
13+
*
14+
* @see https://github.com/mongodb/specifications/blob/ddfc8b583d49aaf8c4c19fa01255afb66b36b92e/source/benchmarking/benchmarking.rst#multi-doc-benchmarks
15+
*/
16+
#[AfterMethods('afterAll')]
17+
final class GridFSBench
18+
{
19+
/** @var resource */
20+
private $stream;
21+
private Bucket $bucket;
22+
private mixed $id;
23+
24+
/** @see https://github.com/mongodb/specifications/blob/ddfc8b583d49aaf8c4c19fa01255afb66b36b92e/source/benchmarking/benchmarking.rst#gridfs-upload */
25+
#[BeforeMethods('beforeUpload')]
26+
public function benchUpload(): void
27+
{
28+
$this->bucket->uploadFromStream('test', $this->stream);
29+
}
30+
31+
public function beforeUpload(): void
32+
{
33+
$database = Utils::getDatabase();
34+
$database->drop();
35+
36+
$this->bucket = $database->selectGridFSBucket();
37+
// Init the GridFS bucket
38+
$this->bucket->uploadFromStream('init', Data::getStream(1));
39+
// Prepare the 50MB stream to upload
40+
$this->stream = Data::getStream(50 * 1024 * 1024);
41+
}
42+
43+
/** @see https://github.com/mongodb/specifications/blob/ddfc8b583d49aaf8c4c19fa01255afb66b36b92e/source/benchmarking/benchmarking.rst#gridfs-download */
44+
#[BeforeMethods('beforeDownload')]
45+
public function benchDownload(): void
46+
{
47+
$this->bucket->downloadToStream($this->id, $this->stream);
48+
}
49+
50+
public function beforeDownload(): void
51+
{
52+
$database = Utils::getDatabase();
53+
$database->drop();
54+
55+
$this->bucket = $database->selectGridFSBucket();
56+
// Upload a 50MB file
57+
$this->id = $this->bucket->uploadFromStream('init', Data::getStream(50 * 1024 * 1024));
58+
// Prepare the stream to receive the download
59+
$this->stream = Data::getStream(0);
60+
}
61+
62+
public function afterAll(): void
63+
{
64+
unset($this->bucket, $this->stream, $this->id);
65+
Utils::getDatabase()->drop();
66+
}
67+
}

benchmark/DriverBench/MultiDocBench.php

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use MongoDB\Benchmark\Fixtures\Data;
77
use MongoDB\Benchmark\Utils;
88
use MongoDB\BSON\Document;
9+
use MongoDB\GridFS\Bucket;
910
use PhpBench\Attributes\BeforeMethods;
1011
use PhpBench\Attributes\ParamProviders;
1112

@@ -17,19 +18,18 @@
1718
*
1819
* @see https://github.com/mongodb/specifications/blob/ddfc8b583d49aaf8c4c19fa01255afb66b36b92e/source/benchmarking/benchmarking.rst#multi-doc-benchmarks
1920
*/
20-
#[BeforeMethods('prepareDatabase')]
21-
class MultiDocBench
21+
final class MultiDocBench
2222
{
23-
public function prepareDatabase(): void
24-
{
25-
Utils::getCollection()->drop();
26-
}
23+
/** @var resource */
24+
private $stream;
25+
private Bucket $bucket;
26+
private mixed $id;
2727

2828
/**
2929
* @see https://github.com/mongodb/specifications/blob/master/source/benchmarking/benchmarking.rst#find-many-and-empty-the-cursor
3030
* @param array{options: array} $params
3131
*/
32-
#[BeforeMethods('setupFindMany')]
32+
#[BeforeMethods('beforeFindMany')]
3333
#[ParamProviders('provideFindManyParams')]
3434
public function benchFindMany(array $params): void
3535
{
@@ -40,11 +40,14 @@ public function benchFindMany(array $params): void
4040
foreach ($collection->find([], $params['options']) as $document);
4141
}
4242

43-
public function setupFindMany(): void
43+
public function beforeFindMany(): void
4444
{
45+
$collection = Utils::getCollection();
46+
$collection->drop();
47+
4548
$tweet = Data::readJsonFile(Data::TWEET_FILE_PATH);
4649
$documents = array_fill(0, 9_999, $tweet);
47-
Utils::getCollection()->insertMany($documents);
50+
$collection->insertMany($documents);
4851
}
4952

5053
public static function provideFindManyParams(): Generator
@@ -63,7 +66,7 @@ public static function provideFindManyParams(): Generator
6366
* @see https://github.com/mongodb/specifications/blob/ddfc8b583d49aaf8c4c19fa01255afb66b36b92e/source/benchmarking/benchmarking.rst#large-doc-bulk-insert
6467
* @param array{documents: array} $params
6568
*/
66-
#[BeforeMethods('setupBulkInsert')]
69+
#[BeforeMethods('beforeBulkInsert')]
6770
#[ParamProviders('provideBulkInsertParams')]
6871
public function benchBulkInsert(array $params): void
6972
{
@@ -74,12 +77,11 @@ public function benchBulkInsert(array $params): void
7477
$collection->insertMany($params['documents']);
7578
}
7679

77-
public function setupBulkInsert(): void
80+
public function beforeBulkInsert(): void
7881
{
79-
$collectionName = Utils::getCollection()->getCollectionName();
80-
Utils::getClient()
81-
->selectDatabase(Utils::getDatabase())
82-
->createCollection($collectionName);
82+
$database = Utils::getDatabase();
83+
$database->dropCollection(Utils::getCollectionName());
84+
$database->createCollection(Utils::getCollectionName());
8385
}
8486

8587
public static function provideBulkInsertParams(): Generator

benchmark/Extension/EnvironmentProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private function getServerInfo(Manager $manager): array
6161
private function getBuildInfo(Manager $manager): array
6262
{
6363
$buildInfo = $manager->executeCommand(
64-
Utils::getDatabase(),
64+
Utils::getDatabaseName(),
6565
new Command(['buildInfo' => 1]),
6666
new ReadPreference(ReadPreference::PRIMARY),
6767
)->toArray()[0];

benchmark/Fixtures/Data.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
namespace MongoDB\Benchmark\Fixtures;
44

55
use function file_get_contents;
6+
use function fopen;
7+
use function fwrite;
68
use function json_decode;
9+
use function rewind;
10+
use function str_repeat;
711

812
use const JSON_THROW_ON_ERROR;
913

@@ -17,4 +21,18 @@ public static function readJsonFile(string $path): array
1721
{
1822
return json_decode(file_get_contents($path), true, 512, JSON_THROW_ON_ERROR);
1923
}
24+
25+
/**
26+
* Generates an in-memory stream of the given size.
27+
*
28+
* @return resource
29+
*/
30+
public static function getStream(int $size)
31+
{
32+
$stream = fopen('php://memory', 'w+');
33+
fwrite($stream, str_repeat("\0", $size));
34+
rewind($stream);
35+
36+
return $stream;
37+
}
2038
}

benchmark/Utils.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,43 @@
44

55
use MongoDB\Client;
66
use MongoDB\Collection;
7+
use MongoDB\Database;
78

89
use function getenv;
910

1011
final class Utils
1112
{
1213
private static ?Client $client;
14+
private static ?Database $database;
1315
private static ?Collection $collection;
1416

1517
public static function getClient(): Client
1618
{
17-
return self::$client ??= self::createClient();
19+
return self::$client ??= new Client(self::getUri());
20+
}
21+
22+
public static function getDatabase(): Database
23+
{
24+
return self::$database ??= self::getClient()->selectDatabase(self::getDatabaseName());
1825
}
1926

2027
public static function getCollection(): Collection
2128
{
22-
return self::$collection ??= self::createCollection();
29+
return self::$collection ??= self::getDatabase()->selectCollection(self::getCollectionName());
2330
}
2431

2532
public static function getUri(): string
2633
{
2734
return getenv('MONGODB_URI') ?: 'mongodb://localhost:27017/';
2835
}
2936

30-
public static function getDatabase(): string
37+
public static function getDatabaseName(): string
3138
{
3239
return getenv('MONGODB_DATABASE') ?: 'phplib_test';
3340
}
3441

35-
private static function createClient(): Client
36-
{
37-
return new Client(self::getUri());
38-
}
39-
40-
private static function createCollection(): Collection
42+
public static function getCollectionName(): string
4143
{
42-
return self::getClient()->selectCollection(self::getDatabase(), 'perftest');
44+
return 'perftest';
4345
}
4446
}

phpbench.json.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"runner.bootstrap": "vendor/autoload.php",
66
"runner.file_pattern": "*Bench.php",
77
"runner.path": "benchmark",
8+
"runner.php_config": { "memory_limit": "1G" },
89
"runner.iterations": 3,
910
"runner.revs": 10
1011
}

0 commit comments

Comments
 (0)