Created
September 10, 2012 06:35
-
-
Save epitron/154be8f4aae4b1769362 to your computer and use it in GitHub Desktop.
Faster 'require' method
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
echo -n "with: " | |
time ruby -I. -rfast-require -e 'require "epitools"' | |
echo -n "without: " | |
time ruby -e 'require "epitools"' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
load "fast-require.rb" | |
# require 'pry-rescue' | |
# Pry.rescue { load "/home/epi/.gem/bin/rails" } | |
load "/home/epi/.gem/bin/rails" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
$:.unshift File.dirname(__FILE__) | |
require 'cdb' | |
class Gem::Database | |
DBFILE = File.expand_path "~/.gems.cdb" | |
def self.find(file) | |
DB[file] || DB[file+".rb"] || DB[file+".so"] | |
end | |
def self.rebuild! | |
CDBMake.open(DBFILE) do |db| | |
stdlibs = RbConfig::CONFIG.values_at("rubylibdir", "archdir", "sitelibdir", "sitearchdir", "vendorlibdir", "vendorarchdir") | |
paths = stdlibs + Gem.all_load_paths | |
p paths | |
paths.each do |path| | |
Dir["#{path}/**/*"].each do |filepath| | |
unless File.directory? filepath | |
filepath["#{path}/"] = "" | |
db[filepath] = path | |
end | |
end | |
end | |
end # CDBMake | |
end | |
def self.exists? | |
File.exists? DBFILE | |
end | |
rebuild! if not exists? | |
DB = CDB.new DBFILE | |
end | |
alias gem_original_autoload autoload | |
# def eagerload(const, path, &block) | |
# if block_given? | |
# yield | |
# else | |
# require(path) | |
# end | |
# end | |
# alias autoload eagerload | |
def autoload(const, path=nil, &block) | |
raise "Error: autoreq must be supplied with a file to load, or a block." unless !!path ^ block_given? | |
if block_given? | |
Module.autoreqs[const] = block | |
else | |
Module.autoreqs[const] = path | |
end | |
end | |
class Module | |
@@autoreq_is_searching_for = nil | |
alias const_missing_without_autoreq const_missing | |
def const_missing(const) | |
return if const == @@autoreq_is_searching_for | |
if thing = autoreqs[const] | |
case thing | |
when String, Symbol | |
require thing | |
when Proc | |
Object.class_eval(&thing) | |
else | |
raise "Error: Don't know how to autoload a #{thing.class}: #{thing.inspect}" | |
end | |
end | |
@@autoreq_is_searching_for = const | |
const_get(const) || const_missing_without_autoreq(const) | |
end | |
def autoreqs | |
@@autoreqs ||= {} | |
end | |
end | |
def require path | |
p [:require, path] | |
if loadpath = Gem::Database.find(path+".rb") | |
p :found_it | |
require_relative("#{loadpath}/#{path}.rb") | |
return | |
end | |
if Gem.unresolved_deps.empty? then | |
p :resolved | |
gem_original_require path | |
else | |
p :unresolved | |
spec = Gem::Specification.find { |s| | |
s.activated? and s.contains_requirable_file? path | |
} | |
unless spec then | |
found_specs = Gem::Specification.find_in_unresolved path | |
unless found_specs.empty? then | |
found_specs = [found_specs.last] | |
else | |
found_specs = Gem::Specification.find_in_unresolved_tree path | |
end | |
found_specs.each do |found_spec| | |
found_spec.activate | |
end | |
end | |
return gem_original_require path | |
end | |
rescue LoadError => load_error | |
if load_error.message.start_with?("Could not find") or | |
(load_error.message.end_with?(path) and Gem.try_activate(path)) then | |
return gem_original_require(path) | |
end | |
raise load_error | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$:.unshift "." | |
require 'epitools' | |
require 'cdb' | |
require 'dbm' | |
dbfile = Path["gems.marshal"] | |
if dbfile.exists? | |
time { $db = dbfile.unmarshal } | |
else | |
time do | |
db = {} | |
Gem.all_load_paths.each do |path| | |
puts path | |
Dir["#{path}/**/*"].each do |file| | |
unless File.directory? file | |
file["#{path}/"] = "" | |
db[file] = path | |
end | |
end | |
end | |
dbfile.write db.marshal | |
$db = db | |
end | |
end | |
#$db = Hash[$db.to_a.take(50)] | |
class Abstract | |
def benchit | |
$db.keys.each do |k| | |
@db[k] | |
end | |
end | |
end | |
class MarshalDB < Abstract | |
def create | |
Path["db.marshal"].write $db.marshal | |
end | |
def load | |
@db = Path["db.marshal"].unmarshal | |
end | |
end | |
class DBMDB < Abstract | |
def create | |
db = DBM.new("db.dbm") | |
$db.each { |k,v| db[k] = v } | |
db.close | |
end | |
def load | |
@db = DBM.open("db.dbm") | |
end | |
end | |
class CDBDB < Abstract | |
def create | |
CDBMake.open("db.cdb") do |db| | |
$db.each { |k,v| db[k] = v } | |
end | |
end | |
def load | |
@db = CDB.new("db.cdb") | |
end | |
end | |
class JSONDB < Abstract | |
def create | |
Path["db.json"].write $db.to_json | |
end | |
def load | |
@db = Path["db.json"].read_json | |
end | |
end | |
dbclasses = [MarshalDB, JSONDB, DBMDB, CDBDB] | |
dbs = dbclasses.map(&:new) | |
benches = {} | |
actions = %w[create load benchit] | |
dbs.each do |dbobj| | |
actions.each do |action| | |
benches["#{dbobj.class.name}-#{action}"] = proc { dbobj.send(action) } | |
end | |
end | |
bench 1, benches |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
echo -n "with: " | |
strace -o >(wc -l) ruby -I. -rfast-require -e 'require "epitools"' | |
echo -n "without: " | |
strace -o >(wc -l) ruby -e 'require "epitools"' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment