Performance is not as expected, what I'm doing wrong?
Hi everyone! First of all, thanks for your contribution to Rails community. You guys are amazing.
We have an application in production and we have some problems with AMS performance. I'm checking fast_jsonapi to solve this :). I'm testing in my personal project to check the performance about FJA over AMS, but unfortunately I didn't find what I was expecting :( . Maybe I am doing my performance tests in a bad way and you can help me. Here is my benchmark:
Here are my serializers (ASM and FJA)
ASM:
class V1::ReservationSerializer < ActiveModel::Serializer
attributes :id, :building_id, :reference, :start_date, :end_date,
:normal_price, :total_price, :status, :createable_id, :createable_type,
:comment, :accepted_conditions, :channel_id, :discount, :admin_price, :rest,
:booking_reference, :process, :coupon_id, :discount_id, :reservation_condition_id,
:childs, :adults, :client_comments, :created_at, :updated_at
end
FJA:
class V2::ReservationSerializer
include FastJsonapi::ObjectSerializer
attributes :id, :building_id, :reference, :start_date, :end_date,
:normal_price, :total_price, :status, :createable_id, :createable_type,
:comment, :accepted_conditions, :channel_id, :discount, :admin_price, :rest,
:booking_reference, :process, :coupon_id, :discount_id, :reservation_condition_id,
:childs, :adults, :client_comments, :created_at, :updated_at
end
BENCHMARKS
With Benchmark ips:
n = 1000
reservations = Reservation.actives.limit(n)
Benchmark.ips do |x|
x.time = 1
x.report('ASM'){
json1 = ActiveModel::Serializer::CollectionSerializer.new(
reservations,
serializer: ActiveModel::Serializer::V1::ReservationSerializer
)
}
x.report('FJA') {
json2 = ::V2::ReservationSerializer.new(reservations).serialized_json
}
x.compare!
end
Calculating -------------------------------------
ASM 14.096 (± 0.0%) i/s - 15.000 in 1.065103s
FJA 4.048 (± 0.0%) i/s - 5.000 in 1.246974s
Comparison:
ASM: 14.1 i/s
FJA: 4.0 i/s - 3.48x slower
With Benchmark measure:
[1, 25, 250, 1000, 5000].each do |reservations_count|
reservations = Reservation.actives.limit(reservations_count)
time_ams = Benchmark.measure {
json1 = ActiveModel::Serializer::CollectionSerializer.new(reservations, serializer: ActiveModel::Serializer::V1::ReservationSerializer)
}.real * 1000
time_fastjson = Benchmark.measure {
json2 = ::V2::ReservationSerializer.new(reservations).serialized_json
}.real * 1000
Rails.logger.info("Size collection #{reservations_count}: AMS -> #{time_ams}")
Rails.logger.info("Size collection #{reservations_count}: FJA -> #{time_fastjson}")
end
Results:
Size collection 1: AMS -> 1.6655579674988985
Size collection 1: FJA -> 0.6660670042037964
Size collection 25: AMS -> 7.491803960874677
Size collection 25: FJA -> 9.159923996776342
Size collection 250: AMS -> 69.97357797808945
Size collection 250: FJA -> 75.90831100242212
Size collection 1000: AMS -> 257.1048479876481
Size collection 1000: FJA -> 317.56329600466415
Size collection 5000: AMS -> 1393.7372969812714
Size collection 5000: FJA -> 1847.1652650041506
Is anything wrong here? Thanks for helping the community, Cheers!
@luismiv85 In both the AMS serialization, I believe you should do a .as_json at the end else this would just instantiate the object and obviously be faster.
@Charizard I don't understand what you mean. In both case (json1 and json2) return a json. I think is not necessary .as_json after use AMS. ¿Am I missing anything?
@luismiv85 You definitely need to call something like .as_json or .serializable_hash against the ActiveModel serializer… The only thing you're doing right now is initializing an instance of the serializer itself. No serialization is happening