Issue #21987 has been updated by nobu (Nobuyoshi Nakada). byroot (Jean Boussier) wrote:
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.
And no other process renames the directory? ---------------------------------------- Feature #21987: Assume `chdir(2)` isn't called and cache `rb_dir_getwd_ospath()` https://bugs.ruby-lang.org/issues/21987#change-116959 * 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/