Ensonma Performance Serialization JSON - PullRequest
2 голосов
/ 30 мая 2011

Я дергаю себя за волосы, пытаясь оптимизировать одно из моих действий контроллера.Я столкнулся с очень странной проблемой, когда, если я передаю пользовательскую опцию методу 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)

Я даже не передаю нестандартные опции супер.Как это может происходить?

1 Ответ

0 голосов
/ 31 мая 2011

Один из способов найти проблему такого рода - измерить различные кусочки.

Другой способ - поймать ее в действии.Если вы используете отладчик rdb , вы можете произвольно приостановить его и сказать где для отображения стека.Чем больше времени это стоит, тем больше шансов поймать его.

Сделайте это несколько раз.Любая строка кода, которую вы видите в более чем одном образце стека, если вы можете оптимизировать ее, сэкономит значительное время.Это техника случайной паузы . Вот пример , который написан на python, но работает на любом языке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...