Created
August 20, 2020 10:26
-
-
Save casperisfine/6841b967c44fc86f81d39634ccfbb9f7 to your computer and use it in GitHub Desktop.
This file contains 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
# typed: false | |
# frozen_string_literal: true | |
# On MRI Symbols can be of two types: static or dynamic | |
# | |
# Static symbols are the ones explicitly referenced in the source code (`:foo`), and they're fake objects. | |
# Meaning they don't actually exists, they're just a special type of reference like integers. They use close to | |
# no memory, are particularly fast to compare and are not garbage collected. | |
# | |
# Dynamic symbols are symbols built using `String#to_sym` and that don't have an existing equivalent static symbol. | |
# They are true objects instances which exist on the heap and are marked by the garbage collector. | |
# | |
# What this module does, is that it list all the dynamic symbols in existence and append them inside a cache file. | |
# Then on the next boot that file is required early so that all these symbols are created as static symbols. | |
# | |
# Note that there is no cache cleanup, we rely on the cache being invalidated periodically just like bootsnap. | |
module SymbolsCache | |
class << self | |
def update | |
File.open(cache_path, 'a+') do |file| | |
count = ObjectSpace.each_object(Symbol) do |symbol| | |
file.puts(symbol.inspect) | |
end | |
STDERR.puts "[SymbolsCache] #{count} symbols appended to the cache" | |
end | |
end | |
def load | |
require cache_path if File.exist?(cache_path) | |
end | |
private | |
def cache_path | |
File.expand_path('../tmp/cache/bootsnap/symbols_cache.rb', __dir__) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment