Skip to content

Add a small speed up to PathDecanonicalized#2718

Open
elliotgoodrich wants to merge 1 commit intoninja-build:masterfrom
elliotgoodrich:speedup-pathdecanonicalized
Open

Add a small speed up to PathDecanonicalized#2718
elliotgoodrich wants to merge 1 commit intoninja-build:masterfrom
elliotgoodrich:speedup-pathdecanonicalized

Conversation

@elliotgoodrich
Copy link
Contributor

Avoid a mandatory allocation in PathDecanonicalized by taking an output std::string* to append to. Improve its performance by swapping strchr with std::string::find, which can take advantage of knowing the length of the string.

We can also return as soon as we run out of forwardslashes that need to be turned into backslashes, instead of iterating through all forwardslashes.

If backslashes are the common path separator in ninja build files on Windows, it may be worthwhile canonicalizing paths into backslashes-only, which would now allow us to skip the loop entirely in PathDecanonicalized in the case of paths with no forwardslashes.

Rename this function to AppendPathDecanonicalized to reflect its new functionality.

Running manifest_parser_perftest.exe on Windows gives initial timings of:

min 549ms  max 613ms  avg 573.1ms

and timings after this change of:

min 534ms  max 597ms  avg 559.9ms

which is a 2-3% improvement.

Copy link
Contributor

@digit-google digit-google left a comment

Choose a reason for hiding this comment

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

Thanks. great PR. @jhasse please take a look

@elliotgoodrich elliotgoodrich force-pushed the speedup-pathdecanonicalized branch from a2eaf75 to 0028139 Compare February 8, 2026 20:40
src/graph.cc Outdated
c = static_cast<char*>(memchr(c, '/', end - c));

// If `memchr` returns null then there are too many bits in `slash_bits`,
// which happens when we pass `~0` in `build.cc` instead of calculating it.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Found

ninja/src/build.cc

Lines 997 to 1001 in cc60300

// ~0 is assuming that with MSVC-parsed headers, it's ok to always make
// all backslashes (as some of the slashes will certainly be backslashes
// anyway). This could be fixed if necessary with some additional
// complexity in IncludesNormalize::Relativize.
deps_nodes->push_back(state_->GetNode(*i, ~0u));
the other day and added this in to avoid problems until slash_bits is calculated correctly here.

Avoid a mandatory allocation in `PathDecanonicalized` by taking an output
`std::string*` to append to. Improve its performance by swapping
`strchr` with `std::string::find`, which can take advantage of knowing
the length of the string.

We can also return as soon as we run out of forwardslashes that need to be
turned into backslashes, instead of iterating through all
forwardslashes. If backslashes are the common path separator in ninja
build files on Windows, it may be worthwhile canonicalizing paths into
backslashes-only, which would now allow us to skip the loop entirely in
`PathDecanonicalized` in the case of paths with no forwardslashes.

Rename this function to `AppendPathDecanonicalized` to reflect its new
functionality.

Running `manifest_parser_perftest.exe` on Windows gives initial timings
of:

    min 549ms  max 613ms  avg 573.1ms

and timings after this change of:

    min 534ms  max 597ms  avg 559.9ms

which is a 2-3% improvement.
@elliotgoodrich elliotgoodrich force-pushed the speedup-pathdecanonicalized branch from 0028139 to dbd8e7e Compare February 8, 2026 21:46
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