end group :development do - # Access an interactive console on exception pages or by calling 'console' anywhere in the code. - gem 'web-console', '>= 3.3.0' gem 'listen', '>= 3.0.5', '< 3.2' end @@ -43,6 +41,3 @@ group :test do # Easy installation and use of web drivers to run system tests with browsers gem 'webdrivers' end - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
and Such # config/initializers/perf.rb Rails::Engine.prepend( Module.new { def call(*) Benchmark.ips do |x| x.report('call') { super } end super end } )
+ resources :posts do + collection do + get :ok + end + end # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end
Rails::Engine.prepend( Module.new { def call(*) c = GC.stat(:total_allocated_objects) result = super p GC.stat(:total_allocated_objects) - c result end } )
def self.mem result = nil MemoryProfiler.report { result = yield }.pretty_print(retained_strings: 0, allocated_strings: 100, normalize_paths: true) result end end
+63,7 @@ module ActionController # It will be merged with the default Rack environment defined by # +ActionController::Renderer::DEFAULTS+. def initialize(controller, env, defaults) + puts caller @controller = controller @defaults = defaults @env = normalize_keys defaults.merge(env)
s.match?(/A/) }.pretty_print" Total allocated: 0 bytes (0 objects) Total retained: 0 bytes (0 objects) allocated memory by gem ----------------------------------- NO DATA
{a: 2}; MemoryProfiler.report { h = h1.merge(h2); h[:a] = 3; h }.pretty_print" Total allocated: 168 bytes (1 objects) allocated memory by class ----------------------------------- 168 Hash allocated objects by class ----------------------------------- 1 Hash
1}; MemoryProfiler.report { h[:x] || 'hello' }.pretty_print" Total allocated: 0 bytes (0 objects) allocated memory by class ----------------------------------- NO DATA
callbacks to share common setup or constraints between actions. def set_post - @post = Post.find(params[:id]) + Prof.mem do + @post = Post.find(params[:id]) + end end
def translate(*args, **options) cache = @i18n_cache[I18n.locale] ||= {} cache_key = args << options cache[cache_key] || begin result = super cache[cache_key] = result if result result ennd alias t translate end I18n.extend I18nCache
we at least need to handle `:count` option There may be some more corner cases If this approach is too aggressive, maybe we could monkey-patch `Backend#lookup`
most cases, what we need is "data transfer object" instances that are "read only" Such objects can be made more lightweight by dropping some heavy features e.g. dirty tracking, type casting
super unless uppercase_first_letter if (cached = InflectorCache.camelize_cache[term]) cached.dup else super ennd def underscore(camel_cased_word) if (cached = InflectorCache.underscore_cache[camel_cased_word]) cached.dup else super ennd
module SchemaStatementsExtension def columns(table_name) result = super unless InflectorCache.camelize_cache[table_name] InflectorCache.camelize_cache[table_name] = table_name.camelize end unless InflectorCache.underscore_cache[table_name] InflectorCache.underscore_cache[table_name] = table_name.underscor end result ennd ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend SchemaStatementsExtension
obvious bottleneck But we can somehow improve it by micro- optimizations I already pushed so many patches in Rails master, so Rails 6.1 has to be faster than 6.0 After such micro-optimizations, today's benchmark highlighted some performance hotspots
play with! Performance tuning is like a game aiming for a high-score Everybody can play with it for free! Since it's open sourced! I'm waiting for you to join this game!