This PR should improve memory allocation and retained.
Base code
class API < Grape::API
prefix :api
version :v1, using: :path
namespace :test do
2000.times do |index|
get "/test#{index}/" do
'hello'
end
end
end
end
MemoryProfiler.report(allow_files: 'grape') do
API.compile!
end.pretty_print
This code
branch
allocated
retained
master
~85.2 MB (502079 objects)
~15.74 MB (80035 objects)
this branch
~75.34MB (408047 objects)
~13.08 MB (54028 objects)
Difference
~9.96 MB (94032 objects)
~2.66 MB (26007) objects)
Real world app
branch
allocated
retained
master
~64.16 MB (353932 objects)
~9.02 MB (26379 objects)
this branch
~61.44 MB (329231 objects)
~5.86 MB (15271 objects)
Difference
~2.72 MB (24701 objects)
~3.17 MB (11108) objects )
Improve caching
lib/grape/namespace.rb and lib/grape/path.rb were already caching but it could be improved by adding Grape::Router.normalize_path call directly in the cache instead.
Stringify inheritable settings
prefix,namespace and other inheritable settings may be naturally declared with a symbol instead of a string and along compilation, they will be stringified and join create more complex strings. Saving them as string saves some memory allocation.
delete_if instead of -
delete_if will remove elements in the array and returns it. Substracting two arrays will create a new one. Most cases were calling keys and substracting values from its.
Replace AttributesTranslator by ActiveSupport::OrderedOptions
AttributesTranslator is basically a hash with dynamic accessor methods and it is used in lib/grape/router/route.rb and lib/grape/router/greedy_route.rb. These 2 also have an options which is the same data included in the AttributesTranslator. It didn't make sense to keep these two. So, I found that ActiveSupport::OrderedOptions is literally a hash with dynamic accessor methods and it could replace entirely AttributesTranslator. In conjunction with delegate_missing_to, I've successfully drop AttributesTranslator and just add an alias attributes to options.
Introducing base_route.rb
lib/grape/router/greedy_route.rb and lib/grape/router/route.rb are vey close in terms of code so I've created a base_route that both would inherit. It also encapsulated the regexification. I've also added some cache for the regex captures.
This PR should improve memory allocation and retained.
Base code
This code
Real world app
Improve caching
lib/grape/namespace.rb
andlib/grape/path.rb
were already caching but it could be improved by addingGrape::Router.normalize_path
call directly in the cache instead.Stringify inheritable settings
prefix
,namespace
and other inheritable settings may be naturally declared with a symbol instead of a string and along compilation, they will be stringified and join create more complex strings. Saving them as string saves some memory allocation.delete_if
instead of-
delete_if
will remove elements in the array and returns it. Substracting two arrays will create a new one. Most cases were callingkeys
and substracting values from its.Replace
AttributesTranslator
byActiveSupport::OrderedOptions
AttributesTranslator
is basically a hash with dynamic accessor methods and it is used inlib/grape/router/route.rb
andlib/grape/router/greedy_route.rb
. These 2 also have anoptions
which is the same data included in theAttributesTranslator
. It didn't make sense to keep these two. So, I found that ActiveSupport::OrderedOptions is literally a hash with dynamic accessor methods and it could replace entirelyAttributesTranslator
. In conjunction with delegate_missing_to, I've successfully dropAttributesTranslator
and just add an aliasattributes
tooptions
.Introducing base_route.rb
lib/grape/router/greedy_route.rb
andlib/grape/router/route.rb
are vey close in terms of code so I've created abase_route
that both would inherit. It also encapsulated theregexification
. I've also added some cache for the regex captures.Some small refactors
I've refactored some small functions.
Fix #2440