Issue #21987 has been updated by jhawthorn (John Hawthorn). byroot (Jean Boussier) wrote:
For some implementations, allocating a `T_DATA` to avoid leaks in case of failure.
Is this still the case? I removed some of this in https://github.com/ruby/ruby/commit/126b657bd103a1abf4b572ade557ffdc7ae99982, which improved by about 30% on Linux. I had meant to go further like optimistically reading the syscall into a stack buffer instead of using malloc/xmalloc, which it looks like you're already investigating :) ---------------------------------------- Feature #21987: Assume `chdir(2)` isn't called and cache `rb_dir_getwd_ospath()` https://bugs.ruby-lang.org/issues/21987#change-116962 * 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/