Skip to content

Parallel indexing - #3065

Open
AJenbo wants to merge 1 commit into
phpactor:masterfrom
AJenbo:parallel
Open

AJenbo wants to merge 1 commit into
phpactor:masterfrom
AJenbo:parallel

Conversation

@AJenbo

@AJenbo AJenbo commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

I was a bit sad to see that Phpactor is the slowest to index a project, while not being the most CPU hungry, this addresses that by splitting indexing up between sub processes and merging the results in to a single index. Most of the dependencies for this was already there (amphp/process, symfony/process) so only fidry/cpu-core-counter was added as a new dependency.

This result in roughly 6x faster indexing cutting my test project from 3m30s to 35s. This does increase peak memory during indexing but not in an unexpected way.

The PR is a bit on the larger side so I could split it up in a refactor and then add the parallel indexer on top if preferred, but I would prefer not to...

public function assign(array $paths): void
{
$this->chunk = $paths;
$this->input->write(Protocol::encode(

@dantleech dantleech Sep 15, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why use a custom protocol instead of f.e. json + newline? how much more efficient is this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really for performance, unserializing() of objects is simpler and we don't have to worry about thing like UTF encoding and it matches the disk format so felt like less of a gamble.

Comment thread lib/Indexer/Adapter/Php/FileSearchIndex.php
}
}
});
}

@dantleech dantleech Sep 15, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessarily for this PR but would be nice to show some information about the paraellelism in the command output before or after indexing (e.g. how many workers were utilised)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread lib/Phpactor.php
if ($phpactorBin) {
$config[LanguageServerExtension::PARAM_PHPACTOR_BIN] = $phpactorBin;
// Workers do not shre the CWD with the main process so we must resolve relative paths.
$config[IndexerExtension::PARAM_WORKER_BIN] = realpath($phpactorBin) ?: $phpactorBin;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure exactly why this is necessary? Phactor is already spawning workers for other tasks and the CWD is passed as --working-dir?

return new OutsourcedDiagnosticsProvider([
$container->parameter(self::PARAM_PHPACTOR_BIN)->string(),
'language-server:diagnostics',
], $projectPath, $this->logger($container), $container->parameter(self::PARAM_DIAGNOSTIC_OUTSOURCE_TIMEOUT)->int());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need it so that workers use the same version and runtime as the manager process. --working-dir doesn't help here since it sets where the worker resolves the project, but not where the executable is resolved.

@dantleech dantleech left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice. a couple of comments / questions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants