如何解决JSON序列化性能之谜
| 我正在努力优化控制器操作之一。我遇到了一个非常奇怪的问题,如果我将自定义选项传递给as_json方法,它似乎会减慢序列化的速度。下面是一个比较基准。 @location是一个包含约60个位置ActiveRecord对象的数组。x.report(\"as_json\") do
@location.as_json(:methods => [:nearby_categories])
end
x.report(\"js user\") do
@json = @locations.as_json(
:user_data => {:favorites => [],:rank_rewards => []},:methods => [:nearby_categories])
end
区别在于:
as_json 0.000000 0.000000 0.000000 ( 0.000031)
js user 1.320000 0.060000 1.380000 ( 1.390047)
我在位置模型上覆盖了serializable_hash方法:
def serializable_hash(options = {})
only = %w(address business_id city franchise_name id lat lng phone rating state total_reviews zip)
options ||= {}
options[:only] ||= only.map(&:to_sym)
hash = super(:only => options[:only],:except => options[:except],:methods => options[:methods])
# ...
# omitted code which sets additional attributes
# ...
if options && (data = options[:user_data])
fav =
if data && favs = data[:favorites]
favs.select { |f| f.location_id == self.id }.first
else
user.favorites.find_by_location_id(self.id)
end
hash[\"favorite_id\"] = fav ? fav.id : nil
if data && ranks = data[:rank_rewards]
if rank = ranks.select {|urr| urr.location_id == self.id }.first
hash[\"user_rank_level\"] = {:name => rank.rank_reward_level.name,:user_rank_reward_id => rank.id}
end
else
hash[\"user_rank_level\"] = self.user_rank(user)
end
end
hash
end
现在传入两个空数组应该对此代码没有任何影响,只是为了使我确信,我尝试传入一个我不处理的选项:
x.report(\"js user\") do
@json = @locations.as_json(
:garbage => {},:methods => [:nearby_categories])
end
我得到相同的结果:
js user 1.230000 0.070000 1.300000 ( 1.295439)
我什至没有将任何非标准选项传递给super。怎么会这样呢?
解决方法
解决此类问题的一种方法是测量各种零件。
另一种方法是将其陷于行为中。
如果使用rdb调试器,则可以随机暂停它并说出显示堆栈的位置。
花费的时间越多,抓住它的机会就越大。
做几次。
如果可以优化一个堆栈示例中的任何代码行,则可以节省大量时间。
这就是随机暂停技术。
这是一个例子,碰巧是python,但可以使用任何语言。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。