Skip to content

perf: direct syscall fastpath for absolute paths in zend_virtual_cwd - #22722

Open
henderkes wants to merge 3 commits into
php:masterfrom
henderkes:perf/vcwd-direct
Open

henderkes wants to merge 3 commits into
php:masterfrom
henderkes:perf/vcwd-direct

Conversation

@henderkes

@henderkes henderkes commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Absolute paths don't need to go through the per-thread cwd emulation, add a fast-path to directly hand them to libc.

since relative paths won't start with a leading slash, this adds negligible cost for them

<?php
chdir(__DIR__);

$s = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
    file_exists("data.txt");
}
$rel = microtime(true) - $s;

$abs = __DIR__ . "/data.txt";
$s = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
    file_exists($abs);
}
$abs_t = microtime(true) - $s;
workload master patch delta
relative path 0.3521s 0.3524s +0.09%
absolute path 0.3162s 0.2623s −17.05%

Benchmark for Symfony demo:

compilerroutemastervcwd-directdelta
gcc 15/en (home)2741.82868.2+4.61%
gcc 15/en/blog/1038.81066.5+2.67%
clang 21/en (home)2740.72876.8+4.97%
clang 21/en/blog/1031.41065.8+3.34%

cc @dunglas because this will be a nice improvement for frankenphp (though fpm alike) in 8.6 :)

Comment thread Zend/zend_virtual_cwd.c
@henderkes

Copy link
Copy Markdown
Contributor Author

Just realised that this doesn't apply to dirty composer autoloader paths with ../vendor/*. Is there any site resolving a path lexically instead of physically? If not I could drop the dot checks.

@henderkes henderkes left a comment

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.

The only thing I'm not entirely sure is whether we couldn't switch to using fstatat and siblings instead of doing the manual string operations for every path operation that doesn't need the resolved string.

Most importantly, ZTS (/a/c) differs from what NTS is doing (/x/c) when it could be using direct syscalls, get NTS' performance and also resolve (correctly) even for relative paths.

Comment thread Zend/zend_virtual_cwd.c
@arnaud-lb

Copy link
Copy Markdown
Member

The only thing I'm not entirely sure is whether we couldn't switch to using fstatat and siblings instead of doing the manual string operations for every path operation that doesn't need the resolved string.

This would be worth exploring indeed. openat() seems to be available everywhere but Windows, which matches the scope of this patch too, but it could be emulated as well.

@henderkes

Copy link
Copy Markdown
Contributor Author

It's a bit of a larger rework that I wouldn't get ready in time for 8.6 anymore. It would remove a lot of the existing handling separately.

Comment thread Zend/zend_virtual_cwd.c Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants