Skip to content

Commit 567cfe1

Browse files
authored
PHPLIB-1187: Run benchmark on Evergreen (#1185)
* Run benchmark on evergreen * Add evergreen report to benchmark * Only run multiple revs for fast benchmarks * Aim to speed up ParallelMultiFile benchmarks * Skip AMP worker benchmarks in CI
1 parent ba372d5 commit 567cfe1

12 files changed

+191
-54
lines changed

.evergreen/config/functions.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,3 +482,16 @@ functions:
482482
binary: bash
483483
args:
484484
- .evergreen/compile-extension.sh
485+
486+
# Run benchmarks. The filter skips the benchAmpWorkers subjects as they fail due to socket exceptions
487+
"run benchmark":
488+
- command: shell.exec
489+
type: test
490+
params:
491+
working_dir: "src/benchmark"
492+
script: |
493+
${PREPARE_SHELL}
494+
export PATH="${PHP_PATH}/bin:$PATH"
495+
496+
php ../composer.phar install --no-suggest
497+
vendor/bin/phpbench run --report=env --report=evergreen --report=aggregate --output html --filter='bench(?!AmpWorkers)'

.evergreen/config/php.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
extension=mongodb.so
2+
memory_limit=-1

.evergreen/config/test-tasks.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,15 @@ tasks:
2020
commands:
2121
- func: "bootstrap mongohoused"
2222
- func: "run atlas data lake test"
23+
24+
- name: "run-benchmark"
25+
exec_timeout_secs: 3600
26+
commands:
27+
- func: "bootstrap mongo-orchestration"
28+
vars:
29+
TOPOLOGY: "server"
30+
MONGODB_VERSION: "v6.0-perf"
31+
- func: "run benchmark"
32+
- command: perf.send
33+
params:
34+
file: src/benchmark/.phpbench/results.json

.evergreen/config/test-variants.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,18 @@ buildvariants:
114114
tasks:
115115
- "test_atlas_task_group"
116116
- ".csfle"
117+
118+
# Run benchmarks
119+
- name: benchmark-rhel90
120+
tags: ["benchmark", "rhel", "x64"]
121+
display_name: "Benchmark: RHEL 9.0, MongoDB 6.0"
122+
run_on: rhel90-dbx-perf-large
123+
expansions:
124+
FETCH_BUILD_VARIANT: "build-rhel90"
125+
FETCH_BUILD_TASK: "build-php-8.2"
126+
PHP_VERSION: "8.2"
127+
depends_on:
128+
- variant: "build-rhel90"
129+
name: "build-php-8.2"
130+
tasks:
131+
- "run-benchmark"

benchmark/phpbench.json.dist

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@
66
"runner.file_pattern": "*Bench.php",
77
"runner.path": "src",
88
"runner.php_config": { "memory_limit": "1G" },
9-
"runner.iterations": 3,
10-
"runner.revs": 10
9+
"runner.iterations": 3
1110
}

benchmark/src/BSON/DocumentBench.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
use MongoDB\Benchmark\Fixtures\Data;
66
use MongoDB\BSON\Document;
77
use PhpBench\Attributes\BeforeMethods;
8+
use PhpBench\Attributes\Revs;
89
use PhpBench\Attributes\Warmup;
910
use stdClass;
1011

1112
use function file_get_contents;
1213
use function iterator_to_array;
1314

1415
#[BeforeMethods('prepareData')]
16+
#[Revs(10)]
1517
#[Warmup(1)]
1618
final class DocumentBench
1719
{

benchmark/src/BSON/PackedArrayBench.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
use MongoDB\Benchmark\Fixtures\Data;
66
use MongoDB\BSON\PackedArray;
77
use PhpBench\Attributes\BeforeMethods;
8+
use PhpBench\Attributes\Revs;
89
use PhpBench\Attributes\Warmup;
910

1011
use function array_values;
1112
use function iterator_to_array;
1213

1314
#[BeforeMethods('prepareData')]
15+
#[Revs(10)]
1416
#[Warmup(1)]
1517
final class PackedArrayBench
1618
{

benchmark/src/DriverBench/ParallelMultiFileExportBench.php

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use PhpBench\Attributes\BeforeClassMethods;
1616
use PhpBench\Attributes\Iterations;
1717
use PhpBench\Attributes\ParamProviders;
18-
use PhpBench\Attributes\Revs;
1918
use RuntimeException;
2019

2120
use function array_chunk;
@@ -44,7 +43,6 @@
4443
#[AfterClassMethods('afterClass')]
4544
#[AfterMethods('afterIteration')]
4645
#[Iterations(1)]
47-
#[Revs(1)]
4846
final class ParallelMultiFileExportBench
4947
{
5048
public static function beforeClass(): void
@@ -74,15 +72,15 @@ public function afterIteration(): void
7472
* Using a single thread to export multiple files.
7573
* By executing a single Find command for multiple files, we can reduce the number of roundtrips to the server.
7674
*
77-
* @param array{chunk:int} $params
75+
* @param array{chunkSize:int} $params
7876
*/
7977
#[ParamProviders(['provideChunkParams'])]
8078
public function benchSequential(array $params): void
8179
{
82-
foreach (array_chunk(self::getFileNames(), $params['chunk']) as $i => $files) {
80+
foreach (array_chunk(self::getFileNames(), $params['chunkSize']) as $i => $files) {
8381
self::exportFile($files, [], [
84-
'limit' => 5_000 * $params['chunk'],
85-
'skip' => 5_000 * $params['chunk'] * $i,
82+
'limit' => 5_000 * $params['chunkSize'],
83+
'skip' => 5_000 * $params['chunkSize'] * $i,
8684
]);
8785
}
8886
}
@@ -103,12 +101,12 @@ public function benchFork(array $params): void
103101
Utils::reset();
104102

105103
// Create a child process for each chunk of files
106-
foreach (array_chunk(self::getFileNames(), $params['chunk']) as $i => $files) {
104+
foreach (array_chunk(self::getFileNames(), $params['chunkSize']) as $i => $files) {
107105
$pid = pcntl_fork();
108106
if ($pid === 0) {
109107
self::exportFile($files, [], [
110-
'limit' => 5_000 * $params['chunk'],
111-
'skip' => 5_000 * $params['chunk'] * $i,
108+
'limit' => 5_000 * $params['chunkSize'],
109+
'skip' => 5_000 * $params['chunkSize'] * $i,
112110
]);
113111

114112
// Exit the child process
@@ -133,21 +131,21 @@ public function benchFork(array $params): void
133131
/**
134132
* Using amphp/parallel with worker pool
135133
*
136-
* @param array{chunk:int} $params
134+
* @param array{chunkSize:int} $params
137135
*/
138136
#[ParamProviders(['provideChunkParams'])]
139137
public function benchAmpWorkers(array $params): void
140138
{
141-
$workerPool = new ContextWorkerPool(ceil(100 / $params['chunk']), new ContextWorkerFactory());
139+
$workerPool = new ContextWorkerPool(ceil(100 / $params['chunkSize']), new ContextWorkerFactory());
142140

143141
$futures = [];
144-
foreach (array_chunk(self::getFileNames(), $params['chunk']) as $i => $files) {
142+
foreach (array_chunk(self::getFileNames(), $params['chunkSize']) as $i => $files) {
145143
$futures[] = $workerPool->submit(
146144
new ExportFileTask(
147145
files: $files,
148146
options: [
149-
'limit' => 5_000 * $params['chunk'],
150-
'skip' => 5_000 * $params['chunk'] * $i,
147+
'limit' => 5_000 * $params['chunkSize'],
148+
'skip' => 5_000 * $params['chunkSize'] * $i,
151149
],
152150
),
153151
)->getFuture();
@@ -160,13 +158,9 @@ public function benchAmpWorkers(array $params): void
160158

161159
public static function provideChunkParams(): Generator
162160
{
163-
yield 'by 1' => ['chunk' => 1];
164-
yield 'by 2' => ['chunk' => 2];
165-
yield 'by 4' => ['chunk' => 4];
166-
yield 'by 8' => ['chunk' => 8];
167-
yield 'by 13' => ['chunk' => 13];
168-
yield 'by 20' => ['chunk' => 20];
169-
yield 'by 100' => ['chunk' => 100];
161+
yield '100 chunks' => ['chunkSize' => 1];
162+
yield '25 chunks' => ['chunkSize' => 4];
163+
yield '10 chunks' => ['chunkSize' => 10];
170164
}
171165

172166
/**

benchmark/src/DriverBench/ParallelMultiFileImportBench.php

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use PhpBench\Attributes\BeforeMethods;
1717
use PhpBench\Attributes\Iterations;
1818
use PhpBench\Attributes\ParamProviders;
19-
use PhpBench\Attributes\Revs;
2019
use RuntimeException;
2120

2221
use function array_chunk;
@@ -47,7 +46,6 @@
4746
#[AfterClassMethods('afterClass')]
4847
#[BeforeMethods('beforeIteration')]
4948
#[Iterations(1)]
50-
#[Revs(1)]
5149
final class ParallelMultiFileImportBench
5250
{
5351
public static function beforeClass(): void
@@ -73,20 +71,6 @@ public function beforeIteration(): void
7371
$database->createCollection(Utils::getCollectionName());
7472
}
7573

76-
/**
77-
* Using Driver's BulkWrite in a single thread.
78-
* The number of files to import in each iteration is controlled by the "chunk" parameter.
79-
*
80-
* @param array{chunk:int} $params
81-
*/
82-
#[ParamProviders(['provideChunkParams'])]
83-
public function benchBulkWrite(array $params): void
84-
{
85-
foreach (array_chunk(self::getFileNames(), $params['chunk']) as $files) {
86-
self::importFile($files);
87-
}
88-
}
89-
9074
/**
9175
* Using library's Collection::insertMany in a single thread
9276
*/
@@ -116,7 +100,7 @@ public function benchInsertMany(): void
116100
* Using multiple forked threads. The number of threads is controlled by the "chunk" parameter,
117101
* which is the number of files to import in each thread.
118102
*
119-
* @param array{chunk:int} $params
103+
* @param array{chunkSize:int} $params
120104
*/
121105
#[ParamProviders(['provideChunkParams'])]
122106
public function benchFork(array $params): void
@@ -128,7 +112,7 @@ public function benchFork(array $params): void
128112
// of a new libmongoc client.
129113
Utils::reset();
130114

131-
foreach (array_chunk(self::getFileNames(), $params['chunk']) as $files) {
115+
foreach (array_chunk(self::getFileNames(), $params['chunkSize']) as $files) {
132116
$pid = pcntl_fork();
133117
if ($pid === 0) {
134118
self::importFile($files);
@@ -155,16 +139,16 @@ public function benchFork(array $params): void
155139
/**
156140
* Using amphp/parallel with worker pool
157141
*
158-
* @param array{processes:int} $params
142+
* @param array{chunkSize:int} $params
159143
*/
160144
#[ParamProviders(['provideChunkParams'])]
161145
public function benchAmpWorkers(array $params): void
162146
{
163-
$workerPool = new ContextWorkerPool(ceil(100 / $params['chunk']), new ContextWorkerFactory());
147+
$workerPool = new ContextWorkerPool(ceil(100 / $params['chunkSize']), new ContextWorkerFactory());
164148

165149
$futures = array_map(
166150
fn ($files) => $workerPool->submit(new ImportFileTask($files))->getFuture(),
167-
array_chunk(self::getFileNames(), $params['chunk']),
151+
array_chunk(self::getFileNames(), $params['chunkSize']),
168152
);
169153

170154
foreach (Future::iterate($futures) as $future) {
@@ -176,13 +160,9 @@ public function benchAmpWorkers(array $params): void
176160

177161
public function provideChunkParams(): Generator
178162
{
179-
yield 'by 1' => ['chunk' => 1];
180-
yield 'by 2' => ['chunk' => 2];
181-
yield 'by 4' => ['chunk' => 4];
182-
yield 'by 8' => ['chunk' => 8];
183-
yield 'by 13' => ['chunk' => 13];
184-
yield 'by 20' => ['chunk' => 20];
185-
yield 'by 100' => ['chunk' => 100];
163+
yield '100 chunks' => ['chunkSize' => 1];
164+
yield '25 chunks' => ['chunkSize' => 4];
165+
yield '10 chunks' => ['chunkSize' => 10];
186166
}
187167

188168
/**

benchmark/src/DriverBench/SingleDocBench.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use MongoDB\Driver\Command;
1010
use PhpBench\Attributes\BeforeMethods;
1111
use PhpBench\Attributes\ParamProviders;
12-
use PhpBench\Attributes\Revs;
1312

1413
use function array_map;
1514
use function file_get_contents;
@@ -45,7 +44,6 @@ public function benchRunCommand(): void
4544
*/
4645
#[BeforeMethods('beforeFindOneById')]
4746
#[ParamProviders('provideFindOneByIdParams')]
48-
#[Revs(1)]
4947
public function benchFindOneById(array $params): void
5048
{
5149
$collection = Utils::getCollection();
@@ -79,7 +77,6 @@ public static function provideFindOneByIdParams(): Generator
7977
* @param array{document: object|array, repeat: int, options?: array} $params
8078
*/
8179
#[ParamProviders('provideInsertOneParams')]
82-
#[Revs(1)]
8380
public function benchInsertOne(array $params): void
8481
{
8582
$collection = Utils::getCollection();

0 commit comments

Comments
 (0)