-
Notifications
You must be signed in to change notification settings - Fork 264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PHPLIB-1187: Run benchmark on Evergreen #1185
Changes from all commits
2ddd4c7
babb286
1b2486d
710e655
bbcc0f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
extension=mongodb.so | ||
memory_limit=-1 | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,5 @@ | |
"runner.file_pattern": "*Bench.php", | ||
"runner.path": "src", | ||
"runner.php_config": { "memory_limit": "1G" }, | ||
"runner.iterations": 3, | ||
"runner.revs": 10 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed this in favour of increasing revs only for benchmarks that run in the microsecond range. For anything that takes milliseconds, the precision is usually good enough with a single rev. |
||
"runner.iterations": 3 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,6 @@ | |
use PhpBench\Attributes\BeforeClassMethods; | ||
use PhpBench\Attributes\Iterations; | ||
use PhpBench\Attributes\ParamProviders; | ||
use PhpBench\Attributes\Revs; | ||
use RuntimeException; | ||
|
||
use function array_chunk; | ||
|
@@ -44,7 +43,6 @@ | |
#[AfterClassMethods('afterClass')] | ||
#[AfterMethods('afterIteration')] | ||
#[Iterations(1)] | ||
#[Revs(1)] | ||
final class ParallelMultiFileExportBench | ||
{ | ||
public static function beforeClass(): void | ||
|
@@ -74,15 +72,15 @@ public function afterIteration(): void | |
* Using a single thread to export multiple files. | ||
* By executing a single Find command for multiple files, we can reduce the number of roundtrips to the server. | ||
* | ||
* @param array{chunk:int} $params | ||
* @param array{chunkSize:int} $params | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Decided to rename this since I got confused as to what |
||
*/ | ||
#[ParamProviders(['provideChunkParams'])] | ||
public function benchSequential(array $params): void | ||
{ | ||
foreach (array_chunk(self::getFileNames(), $params['chunk']) as $i => $files) { | ||
foreach (array_chunk(self::getFileNames(), $params['chunkSize']) as $i => $files) { | ||
self::exportFile($files, [], [ | ||
'limit' => 5_000 * $params['chunk'], | ||
'skip' => 5_000 * $params['chunk'] * $i, | ||
'limit' => 5_000 * $params['chunkSize'], | ||
'skip' => 5_000 * $params['chunkSize'] * $i, | ||
]); | ||
} | ||
} | ||
|
@@ -103,12 +101,12 @@ public function benchFork(array $params): void | |
Utils::reset(); | ||
|
||
// Create a child process for each chunk of files | ||
foreach (array_chunk(self::getFileNames(), $params['chunk']) as $i => $files) { | ||
foreach (array_chunk(self::getFileNames(), $params['chunkSize']) as $i => $files) { | ||
$pid = pcntl_fork(); | ||
if ($pid === 0) { | ||
self::exportFile($files, [], [ | ||
'limit' => 5_000 * $params['chunk'], | ||
'skip' => 5_000 * $params['chunk'] * $i, | ||
'limit' => 5_000 * $params['chunkSize'], | ||
'skip' => 5_000 * $params['chunkSize'] * $i, | ||
]); | ||
|
||
// Exit the child process | ||
|
@@ -133,21 +131,21 @@ public function benchFork(array $params): void | |
/** | ||
* Using amphp/parallel with worker pool | ||
* | ||
* @param array{chunk:int} $params | ||
* @param array{chunkSize:int} $params | ||
*/ | ||
#[ParamProviders(['provideChunkParams'])] | ||
public function benchAmpWorkers(array $params): void | ||
{ | ||
$workerPool = new ContextWorkerPool(ceil(100 / $params['chunk']), new ContextWorkerFactory()); | ||
$workerPool = new ContextWorkerPool(ceil(100 / $params['chunkSize']), new ContextWorkerFactory()); | ||
|
||
$futures = []; | ||
foreach (array_chunk(self::getFileNames(), $params['chunk']) as $i => $files) { | ||
foreach (array_chunk(self::getFileNames(), $params['chunkSize']) as $i => $files) { | ||
$futures[] = $workerPool->submit( | ||
new ExportFileTask( | ||
files: $files, | ||
options: [ | ||
'limit' => 5_000 * $params['chunk'], | ||
'skip' => 5_000 * $params['chunk'] * $i, | ||
'limit' => 5_000 * $params['chunkSize'], | ||
'skip' => 5_000 * $params['chunkSize'] * $i, | ||
], | ||
), | ||
)->getFuture(); | ||
|
@@ -160,13 +158,9 @@ public function benchAmpWorkers(array $params): void | |
|
||
public static function provideChunkParams(): Generator | ||
{ | ||
yield 'by 1' => ['chunk' => 1]; | ||
yield 'by 2' => ['chunk' => 2]; | ||
yield 'by 4' => ['chunk' => 4]; | ||
yield 'by 8' => ['chunk' => 8]; | ||
yield 'by 13' => ['chunk' => 13]; | ||
yield 'by 20' => ['chunk' => 20]; | ||
yield 'by 100' => ['chunk' => 100]; | ||
yield '100 chunks' => ['chunkSize' => 1]; | ||
yield '25 chunks' => ['chunkSize' => 4]; | ||
yield '10 chunks' => ['chunkSize' => 10]; | ||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,6 @@ | |
use PhpBench\Attributes\BeforeMethods; | ||
use PhpBench\Attributes\Iterations; | ||
use PhpBench\Attributes\ParamProviders; | ||
use PhpBench\Attributes\Revs; | ||
use RuntimeException; | ||
|
||
use function array_chunk; | ||
|
@@ -47,7 +46,6 @@ | |
#[AfterClassMethods('afterClass')] | ||
#[BeforeMethods('beforeIteration')] | ||
#[Iterations(1)] | ||
#[Revs(1)] | ||
final class ParallelMultiFileImportBench | ||
{ | ||
public static function beforeClass(): void | ||
|
@@ -73,20 +71,6 @@ public function beforeIteration(): void | |
$database->createCollection(Utils::getCollectionName()); | ||
} | ||
|
||
/** | ||
* Using Driver's BulkWrite in a single thread. | ||
* The number of files to import in each iteration is controlled by the "chunk" parameter. | ||
* | ||
* @param array{chunk:int} $params | ||
*/ | ||
#[ParamProviders(['provideChunkParams'])] | ||
public function benchBulkWrite(array $params): void | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This subject essentially tests the same as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could keep this and remove the other that is a little less efficient There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason I removed |
||
{ | ||
foreach (array_chunk(self::getFileNames(), $params['chunk']) as $files) { | ||
self::importFile($files); | ||
} | ||
} | ||
|
||
/** | ||
* Using library's Collection::insertMany in a single thread | ||
*/ | ||
|
@@ -116,7 +100,7 @@ public function benchInsertMany(): void | |
* Using multiple forked threads. The number of threads is controlled by the "chunk" parameter, | ||
* which is the number of files to import in each thread. | ||
* | ||
* @param array{chunk:int} $params | ||
* @param array{chunkSize:int} $params | ||
*/ | ||
#[ParamProviders(['provideChunkParams'])] | ||
public function benchFork(array $params): void | ||
|
@@ -128,7 +112,7 @@ public function benchFork(array $params): void | |
// of a new libmongoc client. | ||
Utils::reset(); | ||
|
||
foreach (array_chunk(self::getFileNames(), $params['chunk']) as $files) { | ||
foreach (array_chunk(self::getFileNames(), $params['chunkSize']) as $files) { | ||
$pid = pcntl_fork(); | ||
if ($pid === 0) { | ||
self::importFile($files); | ||
|
@@ -155,16 +139,16 @@ public function benchFork(array $params): void | |
/** | ||
* Using amphp/parallel with worker pool | ||
* | ||
* @param array{processes:int} $params | ||
* @param array{chunkSize:int} $params | ||
*/ | ||
#[ParamProviders(['provideChunkParams'])] | ||
public function benchAmpWorkers(array $params): void | ||
{ | ||
$workerPool = new ContextWorkerPool(ceil(100 / $params['chunk']), new ContextWorkerFactory()); | ||
$workerPool = new ContextWorkerPool(ceil(100 / $params['chunkSize']), new ContextWorkerFactory()); | ||
|
||
$futures = array_map( | ||
fn ($files) => $workerPool->submit(new ImportFileTask($files))->getFuture(), | ||
array_chunk(self::getFileNames(), $params['chunk']), | ||
array_chunk(self::getFileNames(), $params['chunkSize']), | ||
); | ||
|
||
foreach (Future::iterate($futures) as $future) { | ||
|
@@ -176,13 +160,9 @@ public function benchAmpWorkers(array $params): void | |
|
||
public function provideChunkParams(): Generator | ||
{ | ||
yield 'by 1' => ['chunk' => 1]; | ||
yield 'by 2' => ['chunk' => 2]; | ||
yield 'by 4' => ['chunk' => 4]; | ||
yield 'by 8' => ['chunk' => 8]; | ||
yield 'by 13' => ['chunk' => 13]; | ||
yield 'by 20' => ['chunk' => 20]; | ||
yield 'by 100' => ['chunk' => 100]; | ||
yield '100 chunks' => ['chunkSize' => 1]; | ||
yield '25 chunks' => ['chunkSize' => 4]; | ||
yield '10 chunks' => ['chunkSize' => 10]; | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should increase the limit. Otherwise we don't know how much memory is used if it's too much. What is the memory limit of the job runner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason it aborted when it hit a previous 128M limit, apparently ignoring the 1G limit definer in the runner config. We can also report memory usage from the benchmarks using
perf.send
, which would be a better indicator than failing the build when it hits some limit. Want me to add those numbers?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perf.send
is too late if the process crashes, no?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct,
perf.send
would not be executed in that case. With-1
the memory would be unlimited, so the only case in which it would crash is if it used up all memory including the page file, which I'd consider highly unlikely.