Issue #21987 has been updated by byroot (Jean Boussier).
Is this still the case? I removed some of this in
My bad. My first prototype of that change was months ago, this is indeed no longer the case.
which it looks like you're already investigating :)
Yes, that was my backup plan from the start. The problem is that on macOS, `open(2)` is incredibly slow. The performance difference of `getcwd` on Linux vs macOS is about 40x: ``` compare-ruby: ruby 4.1.0dev (2026-04-09T05:19:02Z master c091c186e4) +PRISM [arm64-darwin25] built-ruby: ruby 4.1.0dev (2026-04-09T06:37:20Z get-cwd-cache ea02126d79) +PRISM [arm64-darwin25] ``` | |compare-ruby|built-ruby| |:--------|-----------:|---------:| |Dir.pwd | 105.183k| 113.420k| | | -| 1.08x| Linux (inside virtualized Docker) compare-ruby: ruby 4.1.0dev (2026-04-07T08:26:25Z master fcd210086c) +PRISM [aarch64-linux] built-ruby: ruby 4.1.0dev (2026-04-09T06:38:09Z get-cwd-cache 6774af9ba7) +PRISM [aarch64-linux] | |compare-ruby|built-ruby| |:--------|-----------:|---------:| |Dir.pwd | 4.157M| 5.541M| | | -| 1.33x| But if we can't cache `getcwd`, then I'll try to figure out why it's called so much, and eliminate that. ---------------------------------------- Feature #21987: Assume `chdir(2)` isn't called and cache `rb_dir_getwd_ospath()` https://bugs.ruby-lang.org/issues/21987#change-116964 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- ### Context I'm looking at optimizing Ruby applications boot time, and one very common operation that seems wasteful is that when interpreting relative paths we keep calling `ruby_getcwd()`, even though its result almost never changes (`Dir.chdir` calls are rare). We have 3 distinct implementations of `ruby_getcwd()` depending on the platform, but generally speaking it involves: - One or multiple syscalls (on macOS: `open` + `fnctl` + `stat` + `close`). - `malloc` + `free` - `strdup` + `free` - For some implementations, allocating a `T_DATA` to avoid leaks in case of failure. ### Measure Out of curiosity I measured our monolith. Just booting we end up calling `getcwd(2)` `6931` times, for a total of `90ms` spent in `rb_dir_getwd_ospath()`, but the caching would allow to save a bit more than that, as callers would no longer need to manage that memory. ### Proposal I propose that we cache the result of `ruby_getcwd()`, and only flush the cache when `Dir.chdir` is called. ### Compatibility concern This however assumes that C extensions or other native libraries never call `chdir(2)` after executing Ruby, or at least always reset it before yielding back to Ruby. I'm not aware of any C extension currently doing this, but it would be interesting to perform a `gem-codesearch`. If necessary we can provide `void ruby_cwd_changed(void)` to reset the cache after calling `chdir(2)`. -- https://bugs.ruby-lang.org/