diff --git a/conf/config.neon b/conf/config.neon index 30aaa9df46..5c789651b1 100644 --- a/conf/config.neon +++ b/conf/config.neon @@ -42,6 +42,7 @@ parameters: jobSize: 20 processTimeout: 60.0 maximumNumberOfProcesses: 32 + minimumNumberOfJobsPerProcess: 2 polluteScopeWithLoopInitialAssignments: true polluteScopeWithAlwaysIterableForeach: true polluteCatchScopeWithTryAssignments: false @@ -152,7 +153,8 @@ parametersSchema: parallel: structure([ jobSize: int(), processTimeout: float(), - maximumNumberOfProcesses: int() + maximumNumberOfProcesses: int(), + minimumNumberOfJobsPerProcess: int() ]) polluteScopeWithLoopInitialAssignments: bool() polluteScopeWithAlwaysIterableForeach: bool() @@ -388,6 +390,7 @@ services: arguments: jobSize: %parallel.jobSize% maximumNumberOfProcesses: %parallel.maximumNumberOfProcesses% + minimumNumberOfJobsPerProcess: %parallel.minimumNumberOfJobsPerProcess% - class: PHPStan\Parser\CachedParser diff --git a/src/Parallel/Scheduler.php b/src/Parallel/Scheduler.php index 8b6ebbc33c..541e1bc5a6 100644 --- a/src/Parallel/Scheduler.php +++ b/src/Parallel/Scheduler.php @@ -11,13 +11,18 @@ class Scheduler /** @var int */ private $maximumNumberOfProcesses; + /** @var int */ + private $minimumNumberOfJobsPerProcess; + public function __construct( int $jobSize, - int $maximumNumberOfProcesses + int $maximumNumberOfProcesses, + int $minimumNumberOfJobsPerProcess ) { $this->jobSize = $jobSize; $this->maximumNumberOfProcesses = $maximumNumberOfProcesses; + $this->minimumNumberOfJobsPerProcess = $minimumNumberOfJobsPerProcess; } /** @@ -31,7 +36,10 @@ public function scheduleWork( ): Schedule { $jobs = array_chunk($files, $this->jobSize); - $numberOfProcesses = min(count($jobs), $cpuCores); + $numberOfProcesses = min( + (int) floor(count($jobs) / $this->minimumNumberOfJobsPerProcess), + $cpuCores + ); return new Schedule(min($numberOfProcesses, $this->maximumNumberOfProcesses), $jobs); } diff --git a/tests/PHPStan/Parallel/SchedulerTest.php b/tests/PHPStan/Parallel/SchedulerTest.php index 1eae9ff939..adf59fcf4e 100644 --- a/tests/PHPStan/Parallel/SchedulerTest.php +++ b/tests/PHPStan/Parallel/SchedulerTest.php @@ -13,6 +13,7 @@ public function dataSchedule(): array [ 1, 16, + 1, 50, 115, 1, @@ -21,6 +22,7 @@ public function dataSchedule(): array [ 16, 16, + 1, 30, 124, 5, @@ -29,6 +31,7 @@ public function dataSchedule(): array [ 16, 3, + 1, 30, 124, 3, @@ -37,11 +40,21 @@ public function dataSchedule(): array [ 16, 16, + 1, 10, 298, 16, [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8], ], + [ + 16, + 16, + 2, + 30, + 124, + 2, + [30, 30, 30, 30, 4], + ], ]; } @@ -49,6 +62,7 @@ public function dataSchedule(): array * @dataProvider dataSchedule * @param int $cpuCores * @param int $maximumNumberOfProcesses + * @param int $minimumNumberOfJobsPerProcess * @param int $jobSize * @param int $numberOfFiles * @param int $expectedNumberOfProcesses @@ -57,6 +71,7 @@ public function dataSchedule(): array public function testSchedule( int $cpuCores, int $maximumNumberOfProcesses, + int $minimumNumberOfJobsPerProcess, int $jobSize, int $numberOfFiles, int $expectedNumberOfProcesses, @@ -64,7 +79,7 @@ public function testSchedule( ): void { $files = array_fill(0, $numberOfFiles, 'file.php'); - $scheduler = new Scheduler($jobSize, $maximumNumberOfProcesses); + $scheduler = new Scheduler($jobSize, $maximumNumberOfProcesses, $minimumNumberOfJobsPerProcess); $schedule = $scheduler->scheduleWork($cpuCores, $files); $this->assertSame($expectedNumberOfProcesses, $schedule->getNumberOfProcesses());