From 0a68f87dc5394e9ed8e572adaa216f264823c215 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Sun, 28 Jun 2020 13:22:34 +0200 Subject: [PATCH] Freeze absolute paths to reduce allocations on file operations Most of the `File` methods cast the paths it receives with `FilePathValue` which ultimately delegate to `rb_new_str_frozen`. `rb_new_str_frozen` could be experessed as `str.frozen? ? str : str.dup`. So by freezing the paths passed to the various `File.` methods, we save at least one useless allocation each time, unless the string encoding is incompatible with the file system. ``` s = __FILE__ alloc = GC.stat[:total_allocated_objects] File.realpath(s) p GC.stat[:total_allocated_objects] - alloc # => 3 s = __FILE__.freeze alloc = GC.stat[:total_allocated_objects] File.realpath(s) p GC.stat[:total_allocated_objects] - alloc # => 2 ``` --- lib/zeitwerk/loader.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/zeitwerk/loader.rb b/lib/zeitwerk/loader.rb index 8868705..fd45724 100644 --- a/lib/zeitwerk/loader.rb +++ b/lib/zeitwerk/loader.rb @@ -616,7 +616,7 @@ def set_autoload(parent, cname, abspath) # $LOADED_FEATURES stores real paths since Ruby 2.4.4. We set and save the # real path to be able to delete it from $LOADED_FEATURES on unload, and to # be able to do a lookup later in Kernel#require for manual require calls. - realpath = File.realpath(abspath) + realpath = File.realpath(abspath).freeze parent.autoload(cname, realpath) if logger if ruby?(realpath) @@ -719,7 +719,7 @@ def cpath(parent, cname) def ls(dir) Dir.foreach(dir) do |basename| next if basename.start_with?(".") - abspath = File.join(dir, basename) + abspath = File.join(dir, basename).freeze yield basename, abspath unless ignored_paths.member?(abspath) end end