Skip to content

Instantly share code, notes, and snippets.

@casperisfine
Created August 20, 2020 10:26
Show Gist options
  • Save casperisfine/6841b967c44fc86f81d39634ccfbb9f7 to your computer and use it in GitHub Desktop.
Save casperisfine/6841b967c44fc86f81d39634ccfbb9f7 to your computer and use it in GitHub Desktop.
# 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