bootsnap 1.1.1 → 1.3.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
- SHA1:
3
- metadata.gz: 0ecc363422058c3f1f15e26b8aafa41d3abf3e67
4
- data.tar.gz: 8dccbbc4ea0340eae49f8df2bf3295e16596d91f
2
+ SHA256:
3
+ metadata.gz: a6aa25eb064ffeb1bd2e7588f6741061c1acd0647782ba830ebc872ce8997ff2
4
+ data.tar.gz: 981babf7f6d1dc70cd02e5b7373a1a0770d3ebca39e1488503e7aebc1665f8f2
5
5
  SHA512:
6
- metadata.gz: 9a3ffe705bcc35a61bfdd1560ae3807172dc82532384ae9d87da91e790568c4e0abf925378f4f9d6611e8cea469dd8f70793ac4d2edc39f86181b3a6a2102049
7
- data.tar.gz: bb19b804f025c65af27daedb086fdadd8b8978d3d404ccef045b0f3361ca2719ee961b5c66f81b608294d2191595875de47e06f816eb330ed97f2c33884e23e9
6
+ metadata.gz: 5dc67fe4306e38465bbcec301a169e42a7555ce5541b3d2032cfdf157bf4ff47a25b4403a450f57232f2ae27c69fee8f284fdc94588e671b33af9edff5b6fc2d
7
+ data.tar.gz: de7d7384d6cb6c97b7e32ebf6f00de0e7b9f7a0aa65a76897d0458a1d0a172e8d714ca3d812ed79aef9a34943ef7dcfdbff95413c95dab4d44be13971dd2cf57
data/.rubocop.yml CHANGED
@@ -4,4 +4,17 @@ inherit_from:
4
4
  AllCops:
5
5
  Exclude:
6
6
  - 'vendor/**/*'
7
+ - 'tmp/**/*'
8
+ TargetRubyVersion: '2.2'
7
9
 
10
+ # This doesn't take into account retrying from an exception
11
+ Lint/HandleExceptions:
12
+ Enabled: false
13
+
14
+ # allow String.new to create mutable strings
15
+ Style/EmptyLiteral:
16
+ Enabled: false
17
+
18
+ # allow the use of globals which makes sense in a CLI app like this
19
+ Style/GlobalVars:
20
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,5 +1,13 @@
1
- os: osx
2
1
  language: ruby
3
- rvm: ruby-2.4.0
2
+ sudo: false
3
+
4
+ os:
5
+ - linux
6
+ - osx
7
+
8
+ rvm:
9
+ - ruby-2.4
10
+ - ruby-2.5
11
+
4
12
  before_script: rake
5
- script: bin/testunit
13
+ script: bundle exec bin/testunit
data/CHANGELOG.md CHANGED
@@ -1,3 +1,46 @@
1
+ # 1.3.0
2
+
3
+ * Handle cases where load path entries are symlinked (https://github.com/Shopify/bootsnap/pull/136)
4
+
5
+ # 1.2.1
6
+
7
+ * Fix method visibility of `Kernel#require`.
8
+
9
+ # 1.2.0
10
+
11
+ * Add `LoadedFeaturesIndex` to preserve fix a common bug related to `LOAD_PATH` modifications after
12
+ loading bootsnap.
13
+
14
+ # 1.1.8
15
+
16
+ * Don't cache YAML documents with `!ruby/object`
17
+ * Fix cache write mode on Windows
18
+
19
+ # 1.1.7
20
+
21
+ * Create cache entries as 0775/0664 instead of 0755/0644
22
+ * Better handling around cache updates in highly-parallel workloads
23
+
24
+ # 1.1.6
25
+
26
+ * Assortment of minor bugfixes
27
+
28
+ # 1.1.5
29
+
30
+ * bugfix re-release of 1.1.4
31
+
32
+ # 1.1.4 (yanked)
33
+
34
+ * Avoid loading a constant twice by checking if it is already defined
35
+
36
+ # 1.1.3
37
+
38
+ * Properly resolve symlinked path entries
39
+
40
+ # 1.1.2
41
+
42
+ * Minor fix: deprecation warning
43
+
1
44
  # 1.1.1
2
45
 
3
46
  * Fix crash in `Native.compile_option_crc32=` on 32-bit platforms.
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at burke@libbey.me. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in bootsnap.gemspec
4
4
  gemspec
5
+
6
+ group :development do
7
+ gem 'rubocop'
8
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Shopify, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.jp.md ADDED
@@ -0,0 +1,229 @@
1
+ # Bootsnap [![Build Status](https://travis-ci.org/Shopify/bootsnap.svg?branch=master)](https://travis-ci.org/Shopify/bootsnap)
2
+
3
+ Bootsnap は RubyVM におけるバイトコード生成やファイルルックアップ等の時間のかかる処理を最適化するためのライブラリです。ActiveSupport や YAML もサポートしています。[内部動作](#内部動作)もご覧ください。
4
+
5
+ 注意書き: このライブラリは英語話者によって管理されています。この README は日本語ですが、日本語でのサポートはしておらず、リクエストにお答えすることもできません。バイリンガルの方がサポートをサポートしてくださる場合はお知らせください!:)
6
+
7
+ ### パフォーマンス
8
+
9
+ * [Discourse](https://github.com/discourse/discourse) では、約6秒から3秒まで、約50%の起動時間短縮が確認されています。
10
+ * 小さなアプリケーションでも、50%の改善(3.6秒から1.8秒)が確認されています。
11
+ * 非常に巨大でモノリシックなアプリである Shopify のプラットフォームでは、約25秒から6.5秒へと約75%短縮されました。
12
+
13
+ ## 使用方法
14
+
15
+ この gem は MacOS と Linux で作動します。まずは、`bootsnap` を `Gemfile` に追加します:
16
+
17
+ ```ruby
18
+ gem 'bootsnap', require: false
19
+ ```
20
+
21
+ Rails を使用している場合は、以下のコードを、`config/boot.rb` 内にある `require 'bundler/setup'` の直後に追加してください。
22
+
23
+ ```ruby
24
+ require 'bootsnap/setup'
25
+ ```
26
+
27
+ この require の仕組みは[こちら](https://github.com/Shopify/bootsnap/blob/master/lib/bootsnap/setup.rb)で確認できます。
28
+
29
+ Rails を使用していない場合、または、より多くの設定を変更したい場合は、以下のコードを `require 'bundler/setup'` の直後に追加してください(早く読み込まれるほど、より多くのものを最適化することができます)。
30
+
31
+ ```ruby
32
+ require 'bootsnap'
33
+ env = ENV['RAILS_ENV'] || "development"
34
+ Bootsnap.setup(
35
+  cache_dir:           'tmp/cache',         # キャッシュファイルを保存する path
36
+  development_mode:     env == 'development', # 現在の作業環境、例えば RACK_ENV, RAILS_ENV など。
37
+ load_path_cache: true, # キャッシュで LOAD_PATH を最適化する。
38
+  autoload_paths_cache: true,                 # キャッシュで ActiveSupport による autoload を行う。
39
+  disable_trace:       true,                 # (アルファ) `RubyVM::InstructionSequence.compile_option = { trace_instruction: false }`をセットする。
40
+  compile_cache_iseq:   true,                 # ISeq キャッシュをコンパイルする
41
+  compile_cache_yaml:   true                 # YAML キャッシュをコンパイルする
42
+ )
43
+ ```
44
+
45
+ **ヒント**: `require 'bootsnap'` を `BootLib::Require.from_gem('bootsnap', 'bootsnap')` で、 [こちらのトリック](https://github.com/Shopify/bootsnap/wiki/Bootlib::Require)を使って置き換えることができます。こうすると、巨大な`$LOAD_PATH`がある場合でも、起動時間を最短化するのに役立ちます。
46
+
47
+ 注意: Bootsnap と [Spring](https://github.com/rails/spring) は別領域の問題を扱うツールです。Bootsnap は個々のソースファイルの読み込みを高速化します。一方で、Spring は起動されたRailsプロセスのコピーを保持して次回の起動時に起動プロセスの一部を完全にスキップします。2つのツールはうまく連携しており、どちらも新しく生成された Rails アプリケーションにデフォルトで含まれています。
48
+
49
+ ### 環境
50
+ Bootsnapのすべての機能はセットアップ時の設定に従って開発、テスト、プロダクション、および他のすべての環境で有効化されます。Shopify では、この gem を問題なくすべての環境で安全に使用しています。
51
+
52
+ 特定の環境で機能を無効にする場合は、必要に応じて適切な ENV 変数または設定を考慮して設定を変更することをおすすめします。
53
+
54
+ ## 内部動作
55
+
56
+ Bootsnap は、処理に時間のかかるメソッドの結果をキャッシュすることで最適化しています。これは、大きく分けて2つのカテゴリに分けられます。
57
+
58
+ * [Path Pre-Scanning](#path-pre-scanning)
59
+ * `Kernel#require` と `Kernel#load` を `$LOAD_PATH` フルスキャンを行わないように変更します。
60
+   * `ActiveSupport::Dependencies.{autoloadable_module?,load_missing_constant,depend_on}` を `ActiveSupport::Dependencies.autoload_paths` のフルスキャンを行わないようにオーバーライドします。
61
+ * [Compilation caching](#compilation-caching)
62
+  * Ruby バイトコードのコンパイル結果をキャッシュするためのメソッド `RubyVM::InstructionSequence.load_iseq` が実装されています。
63
+   * `YAML.load_file` を YAML オブジェクトのロード結果を MessagePack でキャッシュするように変更します。 MessagePack でサポートされていないタイプが使われている場合は Marshal が使われます。
64
+
65
+ ### Path Pre-Scanning
66
+
67
+ _(このライブラリは [bootscale](https://github.com/byroot/bootscale) という別のライブラリを元に開発されました)_
68
+
69
+ Bootsnap の初期化時、あるいはパス(例えば、`$LOAD_PATH`)の変更時に、`Bootsnap::LoadPathCache` がキャッシュから必要なエントリーのリストを読み込みます。または、必要に応じてフルスキャンを実行し結果をキャッシュします。
70
+ その後、たとえば `require 'foo'` を評価する場合, Ruby は `$LOAD_PATH` `['x', 'y', ...]` のすべてのエントリーを繰り返し評価することで `x/foo.rb`, `y/foo.rb` などを探索します。これに対して Bootsnap は、キャッシュされた reuiqre 可能なファイルと `$LOAD_PATH` を見ることで、Rubyが最終的に選択するであろうパスで置き換えます。
71
+
72
+ この動作によって生成された syscall を見ると、最終的な結果は以前なら次のようになります。
73
+
74
+ ```
75
+ open x/foo.rb # (fail)
76
+ # (imagine this with 500 $LOAD_PATH entries instead of two)
77
+ open y/foo.rb # (success)
78
+ close y/foo.rb
79
+ open y/foo.rb
80
+ ...
81
+ ```
82
+
83
+ これが、次のようになります:
84
+
85
+ ```
86
+ open y/foo.rb
87
+ ...
88
+ ```
89
+
90
+ `autoload_paths_cache` オプションが `Bootsnap.setup` に与えられている場合、`ActiveSupport::Dependencies.autoload_paths` をトラバースする方法にはまったく同じ最適化が使用されます。
91
+
92
+ `*_path_cache` を機能させるオーバーライドを図にすると、次のようになります。
93
+
94
+ ![Bootsnapの説明図](https://cloud.githubusercontent.com/assets/3074765/24532120/eed94e64-158b-11e7-9137-438d759b2ac8.png)
95
+
96
+ Bootsnap は、 `$LOAD_PATH` エントリを安定エントリと不安定エントリの2つのカテゴリに分類します。不安定エントリはアプリケーションが起動するたびにスキャンされ、そのキャッシュは30秒間だけ有効になります。安定エントリーに期限切れはありません。コンテンツがスキャンされると、決して変更されないものとみなされます。
97
+
98
+ 安定していると考えられる唯一のディレクトリは、Rubyのインストールプレフィックス (`RbConfig::CONFIG['prefix']`, または `/usr/local/ruby` や `~/.rubies/x.y.z`)下にあるものと、`Gem.path` (たとえば `~/.gem/ruby/x.y.z`) や `Bundler.bundle_path` 下にあるものです。他のすべては不安定エントリと分類されます。
99
+
100
+ [`Bootsnap::LoadPathCache::Cache`](https://github.com/Shopify/bootsnap/blob/master/lib/bootsnap/load_path_cache/cache.rb) に加えて次の図では、エントリの解決がどのように機能するかを理解するのに役立つかもしれません。経路探索は以下のようになります。
101
+
102
+ ![パス探索の仕組み](https://cloud.githubusercontent.com/assets/3074765/25388270/670b5652-299b-11e7-87fb-975647f68981.png)
103
+
104
+ また、`LoadError` のスキャンがどれほど重いかに注意を払うことも大切です。もし Ruby が `require 'something'` を評価し、そのファイルが `$LOAD_PATH` にない場合は、それを知るために `2 * $LOAD_PATH.length` のファイルシステムアスセスが必要になります。Bootsnap は、ファイルシステムにまったく触れずに `LoadError` を投げ、この結果をキャッシュします。
105
+
106
+ ## Compilation Caching
107
+
108
+ *(このコンセプトのより分かりやすい解説は [yomikomu](https://github.com/ko1/yomikomu) をお読み下さい。)*
109
+
110
+ Ruby には複雑な文法が実装されており、構文解析は簡単なオペレーションではありません。1.9以降、Ruby は Ruby ソースを内部のバイトコードに変換した後、Ruby VM によって実行してきました。2.3.0 以降、[RubyはAPIを公開し](https://ruby-doc.org/core-2.3.0/RubyVM/InstructionSequence.html)、そのバイトコードをキャッシュすることができるようになりました。これにより、同じファイルが複数ロードされた時の、比較的時間のかかる部分をバイパスすることができます。
111
+
112
+ また、アプリケーションの起動時に YAML ドキュメントの読み込みに多くの時間を費やしていることを発見しました。そして、 MessagePack と Marshal は deserialization にあたって YAML よりもはるかに高速であるということに気付きました。そこで、YAML ドキュメントを、Ruby バイトコードと同じコンパイルキャッシングの最適化を施すことで、高速化しています。Ruby の "バイトコード" フォーマットに相当するものは MessagePack ドキュメント (あるいは、MessagePack をサポートしていないタイプの YAML ドキュメントの場合は、Marshal stream)になります。
113
+
114
+ これらのコンパイル結果は、入力ファイル(FNV1a-64)のフルパスのハッシュを取って生成されたファイル名で、キャッシュディレクトリに保存されます。
115
+
116
+ Bootsnap 無しでは、ファイルを `require` するために生成された syscall の順序は次のようになっていました:
117
+
118
+ ```
119
+ open /c/foo.rb -> m
120
+ fstat64 m
121
+ close m
122
+ open /c/foo.rb -> o
123
+ fstat64 o
124
+ fstat64 o
125
+ read o
126
+ read o
127
+ ...
128
+ close o
129
+ ```
130
+
131
+ しかし Bootsnap では、次のようになります:
132
+
133
+ ```
134
+ open /c/foo.rb -> n
135
+ fstat64 n
136
+ close n
137
+ open /c/foo.rb -> n
138
+ fstat64 n
139
+ open (cache) -> m
140
+ read m
141
+ read m
142
+ close m
143
+ close n
144
+ ```
145
+
146
+ これは一見劣化していると思われるかもしれませんが、性能に大きな違いがあります。
147
+
148
+ *(両方のリストの最初の3つの syscalls -- `open`, `fstat64`, `close` -- は本質的に有用ではありません。[このRubyパッチ](https://bugs.ruby-lang.org/issues/13378)は、Boosnap と組み合わせることによって、それらを最適化しています)*
149
+
150
+ Bootsnap は、64バイトのヘッダーとそれに続くキャッシュの内容を含んだキャッシュファイルを書き込みます。ヘッダーは、次のいくつかのフィールドで構成されるキャッシュキーです。
151
+
152
+ - `version`、Bootsnapにハードコードされる基本的なスキーマのバージョン
153
+ - `os_version`、(macOS, BSDの) 現在のカーネルバージョンか 、(Linuxの) glibc のバージョンのハッシュ
154
+ - `compile_option`、`RubyVM::InstructionSequence.compile_option` の返り値
155
+ - `ruby_revision`、コンパイルされたRubyのバージョン
156
+ - `size`、ソースファイルのサイズ
157
+ - `mtime`、コンパイル時のソースファイルの最終変更タイムスタンプ
158
+ - `data_size`、バッファに読み込む必要のあるヘッダーに続くバイト数。
159
+
160
+ キーが有効な場合、キャッシュがファイルからロードされます。そうでない場合、キャッシュは再生成され、現在のキャッシュを破棄します。
161
+
162
+ # 最終的なキャッシュ結果
163
+
164
+ 次のファイル構造があるとします。
165
+
166
+ ```
167
+ /
168
+ ├── a
169
+ ├── b
170
+ └── c
171
+ └── foo.rb
172
+ ```
173
+
174
+ そして、このような `$LOAD_PATH` があるとします。
175
+
176
+ ```
177
+ ["/a", "/b", "/c"]
178
+ ```
179
+
180
+ Bootsnap なしで `require 'foo'` を呼び出すと、Ruby は次の順序で syscalls を生成します:
181
+
182
+ ```
183
+ open /a/foo.rb -> -1
184
+ open /b/foo.rb -> -1
185
+ open /c/foo.rb -> n
186
+ close n
187
+ open /c/foo.rb -> m
188
+ fstat64 m
189
+ close m
190
+ open /c/foo.rb -> o
191
+ fstat64 o
192
+ fstat64 o
193
+ read o
194
+ read o
195
+ ...
196
+ close o
197
+ ```
198
+
199
+ しかし Bootsnap では、次のようになります:
200
+
201
+ ```
202
+ open /c/foo.rb -> n
203
+ fstat64 n
204
+ close n
205
+ open /c/foo.rb -> n
206
+ fstat64 n
207
+ open (cache) -> m
208
+ read m
209
+ read m
210
+ close m
211
+ close n
212
+ ```
213
+
214
+ Bootsnap なしで `require 'nope'` を呼び出すと、次のようになります:
215
+
216
+ ```
217
+ open /a/nope.rb -> -1
218
+ open /b/nope.rb -> -1
219
+ open /c/nope.rb -> -1
220
+ open /a/nope.bundle -> -1
221
+ open /b/nope.bundle -> -1
222
+ open /c/nope.bundle -> -1
223
+ ```
224
+
225
+ ...そして、Bootsnap で `require 'nope'` を呼び出すと、次のようになります...
226
+
227
+ ```
228
+ # (nothing!)
229
+ ```
data/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # Bootsnap [![Build Status](https://travis-ci.org/Shopify/bootsnap.svg?branch=master)](https://travis-ci.org/Shopify/bootsnap)
2
2
 
3
- **Beta-quality. See [the last section of this README](#trustworthiness).**
4
-
5
3
  Bootsnap is a library that plugs into Ruby, with optional support for `ActiveSupport` and `YAML`,
6
4
  to optimize and cache expensive computations. See [How Does This Work](#how-does-this-work).
7
5
 
@@ -12,21 +10,26 @@ to optimize and cache expensive computations. See [How Does This Work](#how-does
12
10
 
13
11
  ## Usage
14
12
 
15
- This gem works on MacOS and Linux.
13
+ This gem works on macOS and Linux.
16
14
 
17
15
  Add `bootsnap` to your `Gemfile`:
18
16
 
19
17
  ```ruby
20
- gem 'bootsnap'
18
+ gem 'bootsnap', require: false
21
19
  ```
22
20
 
23
- If you are using rails, add this to `config/boot.rb` immediately after `require 'bundler/setup'`:
21
+ If you are using Rails, add this to `config/boot.rb` immediately after `require 'bundler/setup'`:
24
22
 
25
23
  ```ruby
26
24
  require 'bootsnap/setup'
27
25
  ```
28
26
 
29
- If you are not using rails, or if you are but want more control over things, add this to your
27
+ It's technically possible to simply specify `gem 'bootsnap', require: 'bootsnap/setup'`, but it's
28
+ important to load Bootsnap as early as possible to get maximum performance improvement.
29
+
30
+ You can see how this require works [here](https://github.com/Shopify/bootsnap/blob/master/lib/bootsnap/setup.rb).
31
+
32
+ If you are not using Rails, or if you are but want more control over things, add this to your
30
33
  application setup immediately after `require 'bundler/setup'` (i.e. as early as possible: the sooner
31
34
  this is loaded, the sooner it can start optimizing things)
32
35
 
@@ -48,6 +51,17 @@ Bootsnap.setup(
48
51
  'bootsnap')` using [this trick](https://github.com/Shopify/bootsnap/wiki/Bootlib::Require). This
49
52
  will help optimize boot time further if you have an extremely large `$LOAD_PATH`.
50
53
 
54
+ Note: Bootsnap and [Spring](https://github.com/rails/spring) are orthogonal tools. While Bootsnap
55
+ speeds up the loading of individual source files, Spring keeps a copy of a pre-booted Rails process
56
+ on hand to completely skip parts of the boot process the next time it's needed. The two tools work
57
+ well together, and are both included in a newly-generated Rails applications by default.
58
+
59
+ ### Environments
60
+
61
+ All Bootsnap features are enabled in development, test, production, and all other environments according to the configuration in the setup. At Shopify, we use this gem safely in all environments without issue.
62
+
63
+ If you would like to disable any feature for a certain environment, we suggest changing the configuration to take into account the appropriate ENV var or configuration according to your needs.
64
+
51
65
  ## How does this work?
52
66
 
53
67
  Bootsnap optimizes methods to cache results of expensive computations, and can be grouped
@@ -132,7 +146,7 @@ result too, raising a `LoadError` without touching the filesystem at all.
132
146
 
133
147
  Ruby has complex grammar and parsing it is not a particularly cheap operation. Since 1.9, Ruby has
134
148
  translated ruby source to an internal bytecode format, which is then executed by the Ruby VM. Since
135
- 2.2, Ruby [exposes an API](https://ruby-doc.org/core-2.3.0/RubyVM/InstructionSequence.html) that
149
+ 2.3.0, Ruby [exposes an API](https://ruby-doc.org/core-2.3.0/RubyVM/InstructionSequence.html) that
136
150
  allows caching that bytecode. This allows us to bypass the relatively-expensive compilation step on
137
151
  subsequent loads of the same file.
138
152
 
@@ -264,21 +278,3 @@ open /c/nope.bundle -> -1
264
278
  ```
265
279
  # (nothing!)
266
280
  ```
267
-
268
- ## Trustworthiness
269
-
270
- We use the `*_path_cache` features in production and haven't experienced any issues in a long time.
271
-
272
- The `compile_cache_*` features work well for us in development on macOS. It should work on Linux,
273
- and we intend to deploy it in production, but we haven't yet.
274
-
275
- `disable_trace` should be completely safe, but we don't really use it because some people like to
276
- use tools that make use of `trace` instructions.
277
-
278
- | feature | where we're using it |
279
- |-|-|
280
- | `load_path_cache` | everywhere |
281
- | `autoload_path_cache` | everywhere |
282
- | `disable_trace` | nowhere, but it's safe unless you need tracing |
283
- | `compile_cache_iseq` | development, but probably safe to use everywhere |
284
- | `compile_cache_yaml` | development, but probably safe to use everywhere |