mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Optimised performance for attribute extraction
Disabled all instrumentation unless enabled explicitly
This commit is contained in:
parent
ad886495a1
commit
31ba6fbb08
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,3 +15,4 @@ spec/reports
|
||||
test/tmp
|
||||
test/version_tmp
|
||||
tmp
|
||||
*.swp
|
||||
|
||||
5
Rakefile
5
Rakefile
@ -10,4 +10,9 @@ Rake::TestTask.new(:test) do |t|
|
||||
t.verbose = true
|
||||
end
|
||||
|
||||
desc 'Benchmark'
|
||||
task :bench do
|
||||
load 'bench/perf.rb'
|
||||
end
|
||||
|
||||
task :default => :test
|
||||
|
||||
52
bench/perf.rb
Normal file
52
bench/perf.rb
Normal file
@ -0,0 +1,52 @@
|
||||
require "rubygems"
|
||||
require "bundler/setup"
|
||||
require "active_model_serializers"
|
||||
require "active_support/json"
|
||||
require "benchmark"
|
||||
|
||||
class User < Struct.new(:id,:name,:age,:about)
|
||||
include ActiveModel::SerializerSupport
|
||||
|
||||
def fast_hash
|
||||
h = {
|
||||
id: read_attribute_for_serialization(:id),
|
||||
name: read_attribute_for_serialization(:name),
|
||||
about: read_attribute_for_serialization(:about)
|
||||
}
|
||||
h[:age] = read_attribute_for_serialization(:age) if age > 18
|
||||
h
|
||||
end
|
||||
end
|
||||
|
||||
class UserSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :age, :about
|
||||
|
||||
def include_age?
|
||||
object.age > 18
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
u = User.new(1, "sam", 10, "about")
|
||||
s = UserSerializer.new(u)
|
||||
|
||||
u2 = User.new(2, "sam", 20, "about")
|
||||
s2 = UserSerializer.new(u2)
|
||||
|
||||
p s2.attributes
|
||||
|
||||
p s.attributes
|
||||
|
||||
|
||||
n = 100000
|
||||
|
||||
Benchmark.bmbm {|x|
|
||||
x.report("init") { n.times { UserSerializer.new(u) } }
|
||||
x.report("fast_hash") { n.times { u.fast_hash } }
|
||||
x.report("attributes") { n.times { UserSerializer.new(u).attributes } }
|
||||
x.report("serializable_hash") { n.times { UserSerializer.new(u).serializable_hash } }
|
||||
x.report("serializable_hash_with_instrumentation") { n.times { UserSerializer.new(u).serializable_hash_with_instrumentation } }
|
||||
}
|
||||
|
||||
|
||||
@ -93,6 +93,11 @@ module ActiveModel
|
||||
end
|
||||
|
||||
define_include_method attr
|
||||
|
||||
if self.method_defined? :_fast_attributes
|
||||
undef :_fast_attributes
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def associate(klass, attrs) #:nodoc:
|
||||
@ -279,7 +284,15 @@ module ActiveModel
|
||||
|
||||
# Returns a hash representation of the serializable
|
||||
# object without the root.
|
||||
def serializable_hash
|
||||
def serializable_hash_without_instrumentation
|
||||
return nil if @object.nil?
|
||||
@node = attributes
|
||||
include_associations! if _embed
|
||||
@node
|
||||
end
|
||||
|
||||
|
||||
def serializable_hash_with_instrumentation
|
||||
return nil if @object.nil?
|
||||
instrument(:serialize, :serializer => self.class.name) do
|
||||
@node = attributes
|
||||
@ -290,6 +303,18 @@ module ActiveModel
|
||||
end
|
||||
end
|
||||
|
||||
# disable all instrumentation on serializable_hash (performance will be better)
|
||||
def self.disable_instrumentation!
|
||||
alias_method :serializable_hash, :serializable_hash_without_instrumentation
|
||||
end
|
||||
|
||||
# enable instrumentation for serializable_hash (performance may be impacted)
|
||||
def self.enable_instrumentation!
|
||||
alias_method :serializable_hash, :serializable_hash_with_instrumentation
|
||||
end
|
||||
|
||||
disable_instrumentation!
|
||||
|
||||
def include_associations!
|
||||
_associations.each_key do |name|
|
||||
include!(name) if include?(name)
|
||||
@ -378,13 +403,19 @@ module ActiveModel
|
||||
# Returns a hash representation of the serializable
|
||||
# object attributes.
|
||||
def attributes
|
||||
hash = {}
|
||||
_fast_attributes
|
||||
rescue NameError
|
||||
method = "def _fast_attributes\n"
|
||||
|
||||
_attributes.each do |name,key|
|
||||
hash[key] = read_attribute_for_serialization(name) if include?(name)
|
||||
end
|
||||
method << " h = {}\n"
|
||||
|
||||
hash
|
||||
_attributes.each do |name,key|
|
||||
method << " h[:#{key}] = read_attribute_for_serialization(:#{name}) if send #{INCLUDE_METHODS[name].inspect}\n"
|
||||
end
|
||||
method << " h\nend"
|
||||
|
||||
self.class.class_eval method
|
||||
_fast_attributes
|
||||
end
|
||||
|
||||
# Returns options[:scope]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user