Summary
mcpp run performs a full recursive filesystem scan of large unrelated directories before running a cached root package. With large Git submodules under the repository root, this adds approximately 9.5 seconds to every invocation, even when no compilation is required.
This is especially visible for repositories that keep upstream test corpora or benchmarks as submodules under compat/.
Environment
- mcpp:
0.0.93
- host: Linux x86_64
- toolchain: GCC
16.1.0
- project: source-only C++26 workspace/package
- root package source pattern inferred by mcpp:
src/**/*.{cppm,cpp,cc,c}
The project has large read-only Git submodules which are not package sources:
The root package sources are only under:
Reproduction
From the project root:
/usr/bin/time -f 'real=%e user=%U sys=%S' mcpp run -- --version
/usr/bin/time -f 'real=%e user=%U sys=%S' mcpp run -- --version
Observed:
Finished release [optimized] in 0.03s
Running target/.../mbun
1.3.14
real=9.57 user=4.55 sys=4.99
Finished release [optimized] in 0.03s
Running target/.../mbun
1.3.14
real=9.50 user=4.61 sys=4.86
The same binary does not have this startup cost:
/usr/bin/time -f 'real=%e user=%U sys=%S' target/.../mbun --version
Observed:
1.3.14
real=0.00 user=0.00 sys=0.00
A regular cached build is also fast:
/usr/bin/time -f 'real=%e user=%U sys=%S' mcpp build
Observed:
Finished release [optimized] in 0.02s
real=0.04 user=0.03 sys=0.01
Filesystem evidence
Tracing only file-related syscalls for mcpp run for 15 seconds produced approximately 1,434,120 file operations before timeout. The paths were dominated by unrelated submodules:
compat/node 377,254 path references
compat/bun 133,626 path references
compat 67,084 path references
.mcpp/.xlings 44,676 path references
The command used was:
timeout 15s strace -f -qq -e trace=file \\
-o /tmp/mcpp-files.strace \\
mcpp run -- --version
Process tracing also showed that mcpp only probes the compiler at the beginning (g++ --version, -dumpmachine, -print-sysroot). It does not start a real compile or the mbun binary during the long delay.
Expected behavior
Given an explicit source pattern such as:
mcpp run should not recursively enumerate unrelated directories such as:
compat/bun
compat/node
target
.mcpp
The command should reuse the same source-discovery and dependency-resolution cache as mcpp build, then launch the already-built binary.
Possible implementation direction
- Derive the fixed directory prefix from a source glob and walk only that prefix. For
src/**/*, do not start traversal at ..
- Treat Git submodule boundaries as excluded from package source discovery unless explicitly declared as a package/member.
- Skip generated/cache directories such as
target and .mcpp during source discovery.
- Cache source discovery and resolved dependency metadata so
mcpp run does not repeat the full scan after mcpp build.
- Add a regression test containing a large unrelated directory or submodule and assert that
mcpp run remains close to the cached mcpp build time.
Impact
This makes the normal development command slow for every invocation and becomes worse as compatibility corpora grow. The runtime itself is fast; the delay is entirely in the mcpp run/resolve path.
Summary
mcpp runperforms a full recursive filesystem scan of large unrelated directories before running a cached root package. With large Git submodules under the repository root, this adds approximately 9.5 seconds to every invocation, even when no compilation is required.This is especially visible for repositories that keep upstream test corpora or benchmarks as submodules under
compat/.Environment
0.0.9316.1.0src/**/*.{cppm,cpp,cc,c}The project has large read-only Git submodules which are not package sources:
The root package sources are only under:
Reproduction
From the project root:
Observed:
The same binary does not have this startup cost:
/usr/bin/time -f 'real=%e user=%U sys=%S' target/.../mbun --versionObserved:
A regular cached build is also fast:
/usr/bin/time -f 'real=%e user=%U sys=%S' mcpp buildObserved:
Filesystem evidence
Tracing only file-related syscalls for
mcpp runfor 15 seconds produced approximately 1,434,120 file operations before timeout. The paths were dominated by unrelated submodules:The command used was:
Process tracing also showed that mcpp only probes the compiler at the beginning (
g++ --version,-dumpmachine,-print-sysroot). It does not start a real compile or the mbun binary during the long delay.Expected behavior
Given an explicit source pattern such as:
mcpp runshould not recursively enumerate unrelated directories such as:The command should reuse the same source-discovery and dependency-resolution cache as
mcpp build, then launch the already-built binary.Possible implementation direction
src/**/*, do not start traversal at..targetand.mcppduring source discovery.mcpp rundoes not repeat the full scan aftermcpp build.mcpp runremains close to the cachedmcpp buildtime.Impact
This makes the normal development command slow for every invocation and becomes worse as compatibility corpora grow. The runtime itself is fast; the delay is entirely in the mcpp run/resolve path.