bootscale 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 80513d863b2fdb043fcb25e6fb2ddec6a1ecc1df
4
- data.tar.gz: 67ab4ccbbe25e51f3baee0767b24d53a40f143b2
3
+ metadata.gz: f1bf0e9189a33d19e8121e188f245bc738d7d2fe
4
+ data.tar.gz: 214e8efc673b76c1eb4fdce6a076f72ec8952d86
5
5
  SHA512:
6
- metadata.gz: c4ffc0949fbea19273eca3619cda2893aeae8c4acc625e72bc38bfa77b918ba8df335c8bc88a0fdca60a5826a233f36c47e027e0c0e153a25e94e4f9950b844e
7
- data.tar.gz: 7c0754c91c6ff987ff1ef3700b3d2f20204bdbdb8443d44b095ec7ab677a96d174c93a77d629f459e34ffa6c941454763cb3ea450843ca4a11d6f5b1a1672e89
6
+ metadata.gz: 07d8b865970b3bc77bb10474554dd77c0413fdd6ff2c3b386dfef0809793b9739009d13182fba426c6ac559761865ec8dad68b8d2d10ac876261f4d45933e647
7
+ data.tar.gz: 6702914fcce11e5344ea9ea1af2bbeee95442f4e836ed57251e78cba7e12a57f86e5caf2ee4a2581281b43b6c2fe20744b2b4a48808ebee6d5441af1c770b10e
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Bootscale
2
2
 
3
- Speedup applications boot by caching require calls.
3
+ Speedup applications boot by caching file locations during require calls.
4
4
 
5
5
  Speed gain depends on your number of gems. Under 100 gems you likely won't see the difference,
6
- but for bigger applications it can save 1 to 2 seconds of boot time per 100 gems in the Gemfile.
6
+ but for bigger applications it can save 1 to 3 seconds of boot time per 100 used gems.
7
7
 
8
8
  ## Installation
9
9
 
@@ -23,7 +23,7 @@ If your application is a Rails application, you will find this in `config/boot.r
23
23
 
24
24
  ### Important
25
25
 
26
- Cache should be update everytime `$LOAD_PATH` is modified by calling `Bootscale.regenerate`.
26
+ Cache should be updated everytime `$LOAD_PATH` is modified by calling `Bootscale.regenerate`.
27
27
 
28
28
  For Rails apps it means adding an initializer in `config/application.rb`:
29
29
 
@@ -39,7 +39,14 @@ end
39
39
 
40
40
  ## Faster cache loading
41
41
 
42
- Add the `msgpack` gem and `require 'msgpack'` to gain ~10-30ms of extra load speed by using msgpack.
42
+ Add the `msgpack` gem and `require 'msgpack'` to gain ~10-30ms of extra load speed by using msgpack.
43
+
44
+ ## Under the hood
45
+
46
+ Bootscale caches the absolute location of all requirable files on the $LOAD_PATH and
47
+ patches `require` + `autoload` to use these absolute paths, thereby avoiding having to check all load paths for every require.
48
+
49
+ Problem outlined in this [talk](https://www.youtube.com/watch?v=kwkbrOwLsZY)
43
50
 
44
51
  ## Contributing
45
52
 
@@ -1,17 +1,22 @@
1
1
  module Bootscale
2
2
  class CacheBuilder
3
- attr_reader :entries
4
-
5
3
  def initialize
6
4
  @entries = {}
7
5
  end
8
6
 
7
+ # generate the requireables cache from all current load-path entries
8
+ # each load-path is cached individually, so new ones can be added or removed
9
+ # but added/removed files will not be discovered
9
10
  def generate(load_path)
10
- ordered_entries = load_path.map do |path|
11
+ requireables = load_path.reverse_each.flat_map do |path|
11
12
  path = path.to_s
12
- entries[path] ||= Entry.new(path)
13
+ entries[path] ||= Entry.new(path).requireables
13
14
  end
14
- Hash[ordered_entries.reverse.flat_map(&:features)]
15
+ Hash[requireables]
15
16
  end
17
+
18
+ private
19
+
20
+ attr_reader :entries
16
21
  end
17
22
  end
@@ -1,26 +1,20 @@
1
1
  module Kernel
2
- def require_with_cache(path)
2
+ alias_method :require_without_cache, :require
3
+ def require(path)
3
4
  require_without_cache(Bootscale[path] || path)
4
5
  end
5
-
6
- alias_method :require_without_cache, :require
7
- alias_method :require, :require_with_cache
8
6
  end
9
7
 
10
8
  class << Kernel
11
- def require_with_cache(path)
9
+ alias_method :require_without_cache, :require
10
+ def require(path)
12
11
  require_without_cache(Bootscale[path] || path)
13
12
  end
14
-
15
- alias_method :require_without_cache, :require
16
- alias_method :require, :require_with_cache
17
13
  end
18
14
 
19
15
  class Module
20
- def autoload_with_cache(const, path)
16
+ alias_method :autoload_without_cache, :autoload
17
+ def autoload(const, path)
21
18
  autoload_without_cache(const, Bootscale[path] || path)
22
19
  end
23
-
24
- alias_method :autoload_without_cache, :autoload
25
- alias_method :autoload, :autoload_with_cache
26
20
  end
@@ -4,29 +4,30 @@ module Bootscale
4
4
  RbConfig::CONFIG['DLEXT'],
5
5
  RbConfig::CONFIG['DLEXT2'],
6
6
  ].reject { |ext| !ext || ext.empty? }.map { |ext| ".#{ext}"}
7
- FEATURE_FILES = "**/*{#{DOT_RB},#{DL_EXTENSIONS.join(',')}}"
7
+ REQUIREABLE_FILES = "**/*{#{DOT_RB},#{DL_EXTENSIONS.join(',')}}"
8
8
  NORMALIZE_NATIVE_EXTENSIONS = !DL_EXTENSIONS.include?(DOT_SO)
9
9
  ALTERNATIVE_NATIVE_EXTENSIONS_PATTERN = /\.(o|bundle|dylib)\z/
10
-
11
- attr_reader :path, :features
10
+ SLASH = '/'.freeze
12
11
 
13
12
  def initialize(path)
14
13
  @path = path
15
- @path_prefix = path.end_with?('/'.freeze) ? path : "#{path}/"
16
- @features = list_features
17
14
  end
18
15
 
19
- private
16
+ def requireables
17
+ unless absolute = @path.start_with?(SLASH)
18
+ warn "Bootscale: Cannot speedup load for relative path #{@path}"
19
+ end
20
20
 
21
- def list_features
22
- Dir[File.join(path, FEATURE_FILES)].map do |absolute_path|
23
- relative_path = absolute_path.sub(@path_prefix, ''.freeze)
21
+ path_prefix = (@path.end_with?(SLASH) ? @path.size : @path.size + 1)
22
+ relative_part = path_prefix..-1
23
+ Dir[File.join(@path, REQUIREABLE_FILES)].map do |absolute_path|
24
+ relative_path = absolute_path.slice(relative_part)
24
25
 
25
26
  if NORMALIZE_NATIVE_EXTENSIONS
26
27
  relative_path.sub!(ALTERNATIVE_NATIVE_EXTENSIONS_PATTERN, DOT_SO)
27
28
  end
28
29
 
29
- [relative_path, absolute_path]
30
+ [relative_path, (absolute ? absolute_path : :relative)]
30
31
  end
31
32
  end
32
33
  end
@@ -13,11 +13,12 @@ module Bootscale
13
13
 
14
14
  def dump(load_path, cache)
15
15
  path = cache_path(load_path)
16
- return if File.exist?(path)
17
16
  FileUtils.mkdir_p(File.dirname(path))
18
17
  File.write(path, Serializer.dump(cache), mode: 'wb+')
19
18
  end
20
19
 
20
+ private
21
+
21
22
  if defined?(MessagePack)
22
23
  Serializer = MessagePack
23
24
 
@@ -1,3 +1,3 @@
1
1
  module Bootscale
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.0'
3
3
  end
data/lib/bootscale.rb CHANGED
@@ -9,11 +9,12 @@ module Bootscale
9
9
  def [](path)
10
10
  path = path.to_s
11
11
  return if path.start_with?(LEADING_SLASH)
12
- if path.end_with?(DOT_RB) || path.end_with?(DOT_SO)
13
- cache[path]
12
+ result = if path.end_with?(DOT_RB, DOT_SO)
13
+ @cache[path]
14
14
  else
15
- cache["#{path}#{DOT_RB}"] || cache["#{path}#{DOT_SO}"]
15
+ @cache["#{path}#{DOT_RB}"] || @cache["#{path}#{DOT_SO}"]
16
16
  end
17
+ result unless result == :relative
17
18
  end
18
19
 
19
20
  def setup(options = {})
@@ -26,9 +27,7 @@ module Bootscale
26
27
  @cache = load_cache || save_cache(cache_builder.generate($LOAD_PATH))
27
28
  end
28
29
 
29
- def cache
30
- @cache ||= {}
31
- end
30
+ private
32
31
 
33
32
  def cache_builder
34
33
  @cache_builder ||= CacheBuilder.new
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootscale
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-24 00:00:00.000000000 Z
11
+ date: 2015-08-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Inspired by Aaron Patterson's talk on the subject
14
14
  email: