Permalink
Browse files

Use autoload to delay loading features until we need them.

This yields about a 10% improvement in the time it
takes to initially load rspec-mocks.
  • Loading branch information...
1 parent 5fe844e commit 47d398b46d170c52d3efe8f675914d4c351c6911 @myronmarston myronmarston committed Feb 23, 2014
@@ -0,0 +1,31 @@
+time (for i in {1..100}; do ruby -Ilib:../rspec-support/lib -rrspec/mocks -e ""; done)
+
+# 3 runs before our autoload changes
+# real 0m4.497s
+# user 0m3.662s
+# sys 0m0.677s
+#
+# real 0m4.472s
+# user 0m3.644s
+# sys 0m0.671s
+#
+# real 0m4.465s
+# user 0m3.640s
+# sys 0m0.668s
+
+# 3 runs after our autoload changes:
+#
+# real 0m4.038s
+# user 0m3.274s
+# sys 0m0.609s
+#
+# real 0m4.038s
+# user 0m3.274s
+# sys 0m0.609s
+#
+# real 0m4.038s
+# user 0m3.274s
+# sys 0m0.609s
+
+# It's modest, but that's about a 10% improvement: an average
+# of about 40ms to load rather than 45 ms to load.
View
@@ -14,19 +14,7 @@
require 'rspec/mocks/error_generator'
require 'rspec/mocks/space'
require 'rspec/mocks/extensions/marshal'
-require 'rspec/mocks/any_instance/chain'
-require 'rspec/mocks/any_instance/stub_chain'
-require 'rspec/mocks/any_instance/stub_chain_chain'
-require 'rspec/mocks/any_instance/expect_chain_chain'
-require 'rspec/mocks/any_instance/expectation_chain'
-require 'rspec/mocks/any_instance/message_chains'
-require 'rspec/mocks/any_instance/recorder'
require 'rspec/mocks/mutate_const'
-require 'rspec/mocks/matchers/have_received'
-require 'rspec/mocks/matchers/receive'
-require 'rspec/mocks/matchers/receive_messages'
-require 'rspec/mocks/matchers/receive_message_chain'
-require 'rspec/mocks/message_chain'
require 'rspec/mocks/targets'
require 'rspec/mocks/syntax'
require 'rspec/mocks/configuration'
@@ -114,5 +102,18 @@ class << self; attr_reader :space; end
# @private
IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored'
+
+ # To speed up boot time a bit, delay loading optional or rarely
+ # used features until their first use.
+ autoload :AnyInstance, "rspec/mocks/any_instance"
+ autoload :ExpectChain, "rspec/mocks/message_chain"
+ autoload :StubChain, "rspec/mocks/message_chain"
+
+ module Matchers
+ autoload :HaveReceived, "rspec/mocks/matchers/have_received"
+ autoload :Receive, "rspec/mocks/matchers/receive"
+ autoload :ReceiveMessageChain, "rspec/mocks/matchers/receive_message_chain"
+ autoload :ReceiveMessages, "rspec/mocks/matchers/receive_messages"
+ end
end
end
@@ -0,0 +1,7 @@
+require 'rspec/mocks/any_instance/chain'
+require 'rspec/mocks/any_instance/stub_chain'
+require 'rspec/mocks/any_instance/stub_chain_chain'
+require 'rspec/mocks/any_instance/expect_chain_chain'
+require 'rspec/mocks/any_instance/expectation_chain'
+require 'rspec/mocks/any_instance/message_chains'
+require 'rspec/mocks/any_instance/recorder'
@@ -0,0 +1,20 @@
+module RSpec
+ module Mocks
+ module Matchers
+ # @private
+ class ExpectationCustomization
+ attr_accessor :block
+
+ def initialize(method_name, args, block)
+ @method_name = method_name
+ @args = args
+ @block = block
+ end
+
+ def playback_onto(expectation)
+ expectation.__send__(@method_name, *@args, &@block)
+ end
+ end
+ end
+ end
+end
@@ -1,3 +1,5 @@
+require 'rspec/mocks/matchers/expectation_customization'
+
module RSpec
module Mocks
module Matchers
@@ -101,20 +103,5 @@ def move_block_to_last_customization(block)
end
end
end
-
- # @private
- class ExpectationCustomization
- attr_accessor :block
-
- def initialize(method_name, args, block)
- @method_name = method_name
- @args = args
- @block = block
- end
-
- def playback_onto(expectation)
- expectation.__send__(@method_name, *@args, &@block)
- end
- end
end
end
@@ -1,3 +1,5 @@
+require 'rspec/mocks/matchers/expectation_customization'
+
module RSpec
module Mocks
module Matchers
@@ -37,16 +37,9 @@ def self.disallow_negation(method_name)
private
def matcher_allowed?(matcher)
- ALLOWED_MATCHERS.include?(matcher.class)
+ matcher.class.name.start_with?("RSpec::Mocks::Matchers".freeze)
end
- #@api private
- ALLOWED_MATCHERS = [
- Matchers::Receive,
- Matchers::ReceiveMessages,
- Matchers::ReceiveMessageChain,
- ]
-
def define_matcher(matcher, name, &block)
matcher.__send__(name, @target, &block)
end

0 comments on commit 47d398b

Please sign in to comment.