Skip to content

Instantly share code, notes, and snippets.

@casperisfine
Last active June 28, 2020 22:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save casperisfine/68819290350f8036d48a1d71777d5616 to your computer and use it in GitHub Desktop.
Save casperisfine/68819290350f8036d48a1d71777d5616 to your computer and use it in GitHub Desktop.
require 'bootsnap'
require 'benchmark/ips'
module Bootsnap
module LoadPathCache
module NewPathScanner
REQUIRABLE_EXTENSIONS = [DOT_RB] + DL_EXTENSIONS
NORMALIZE_NATIVE_EXTENSIONS = !DL_EXTENSIONS.include?(LoadPathCache::DOT_SO)
ALTERNATIVE_NATIVE_EXTENSIONS_PATTERN = /\.(o|bundle|dylib)\z/
BUNDLE_PATH = if Bootsnap.bundler?
(Bundler.bundle_path.cleanpath.to_s << LoadPathCache::SLASH).freeze
else
''
end
class << self
def call(path)
path = File.expand_path(path.to_s).freeze
# If the bundle path is a descendent of this path, we do additional
# checks to prevent recursing into the bundle path as we recurse
# through this path. We don't want to scan the bundle path because
# anything useful in it will be present on other load path items.
#
# This can happen if, for example, the user adds '.' to the load path,
# and the bundle path is '.bundle'.
contains_bundle_path = BUNDLE_PATH.start_with?(path)
dirs = []
requirables = []
walk(path, nil) do |relative_path, absolute_path, is_directory|
if is_directory
dirs << relative_path
!contains_bundle_path || !absolute_path.start_with?(BUNDLE_PATH)
elsif relative_path.end_with?(*REQUIRABLE_EXTENSIONS)
requirables << relative_path
end
end
[requirables, dirs]
end
def walk(absolute_dir_path, relative_dir_path, &block)
Dir.foreach(absolute_dir_path) do |name|
next if name.start_with?('.')
relative_path = relative_dir_path ? "#{relative_dir_path}/#{name}" : name.freeze
absolute_path = "#{absolute_dir_path}/#{name}"
if File.directory?(absolute_path)
if yield relative_path, absolute_path, true
walk(absolute_path, relative_path, &block)
end
else
yield relative_path, absolute_path, false
end
end
end
end
end
end
end
PATH = File.expand_path(ARGV.first || '.')
Benchmark.ips do |x|
x.config(time: 20, warmup: 2)
x.report('original') { Bootsnap::LoadPathCache::PathScanner.call(PATH) }
x.report('new') { Bootsnap::LoadPathCache::NewPathScanner.call(PATH) }
x.compare!
end
Warming up --------------------------------------
original 1.000 i/100ms
new 2.000 i/100ms
Calculating -------------------------------------
original 18.595 (± 5.4%) i/s - 372.000 in 20.025736s
new 25.369 (± 3.9%) i/s - 508.000 in 20.037516s
Comparison:
new: 25.4 i/s
original: 18.6 i/s - 1.36x (± 0.00) slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment