bootscale 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: