Rails.env is expensive

I’ve been profiling performance of our app and noticed that all the calls to Rails.env.production? (used extensively) are taking rather long.

After seeing its source, everything was clear:

http://github.com/rails/rails/tree/2bf58aa782d3b493f2d98f153324b93c5b058ba6/railties/lib/initializer.rb#L51-54

First it does a require, then it instantiates a new object on each call. After removing the require and memoizing the object, I’ve upped the performance of our application by 5 req/s.

Is there a reason for the current implementation?

The reason was to make Rails.env callable from inside the initializer block (problem cause by the fact that AS is not loaded by railties but is actually loaded later by AR).

Any ideas on how to make that work?

Honestly, what's so hard about calling RAILS_ENV == "production"
wherever it needs to be called?

The method could overwrite itself on first call.

module Test

def self.env

e = ‘production’

def self.env() ‘development’ end

e

end

end

Test.env # => ‘production’

Test.env # => ‘development’

Sounds OK to me, generally we try to avoid requiring from inside method definitions as they've historically been a cause of performance issues. a simple memoized method would probably do the job too

@_env ||= begin   require   ... end

You can still do that of course, that's fine (though it does not look to me as modern Rails anymore).

But the fact is Rails does provide Rails.env. Thus, analysis and discussion about its implementation makes sense in my view.

Shouldn't this solve the problem ?

      unless defined?(ActiveSupport::StringInquirer)         require 'active_support/string_inquirer'       end