Производительность - множественный вызов ассоциации на объекте - PullRequest
0 голосов
/ 31 октября 2018

У меня есть метод, вызванный для user объекта, который имеет множество documents (связанных).

Внутри метода мне пришлось вызывать documents во многих местах, где вызывающий абонент self по умолчанию.

Поэтому мне было интересно, будет ли он вызывать документы для пользователя так много раз, и подумал, что я позвоню один раз и буду ссылаться по документам, docs = self.documents или docs = documents, и я буду использовать эту ссылку там, где нужны документы пользователя и, таким образом, мы можем избежать вызова документов метода ассоциации на объекте пользователя

Но действительно ли он вызывает снова и снова или просто кеширует его впервые при вызове?

Я проверил в консоли, когда я вызываю user.documents, он загружал документы (вызов db), но позже для того же вызова он не загружался.

Подскажите, как это работает. Хорошо ли использовать ссылочную переменную для первого вызова и использовать ее дальше?

1 Ответ

0 голосов
/ 31 октября 2018

Rails автоматически кэширует результат вызовов базы данных. Из направляющих рельсов :

Кэширование запросов - это функция Rails, которая кэширует результирующий набор, возвращаемый каждым запросом. Если Rails снова встречает тот же запрос для этого запроса, он будет использовать кэшированный результирующий набор, а не снова запускать запрос к базе данных.

Например:

class ProductsController < ApplicationController

  def index
    # Run a find query
    @products = Product.all

    ...

    # Run the same query again
    @products = Product.all
  end

end

Во второй раз, когда тот же запрос выполняется к базе данных, он фактически не попадет в базу данных. Первый раз, когда результат возвращается из запроса, он сохраняется в кеше запросов (в памяти), а второй раз - из памяти.

Однако важно отметить, что кэши запросов создаются в начале действия и уничтожаются в конце этого действия и, таким образом, сохраняются только в течение действия действия. Если вы хотите хранить результаты запросов более настойчиво, вы можете использовать низкоуровневое кэширование.

Моя рекомендация - не назначать ее переменной, поскольку она ничего не делает для улучшения читабельности кода, а разница в производительности незначительна. Это может ввести в заблуждение; если бы я читал код и увидел, что кто-то заменил все звонки на documents на docs, я бы удивился, почему, и чтобы понять почему, мне понадобится время.

В конечном итоге, установка docs = self.documents просто говорит Ruby «docs должен указывать на ту же область памяти, что и self.documents», и независимо от того, какую из них вы вызываете, Ruby будет возвращать те же данные из той же области памяти. Существует разница в производительности между вызовом метода и вызовом переменной, но эта разница в производительности настолько мала по сравнению с чем-то вроде скорости вызова базы данных, что ее можно игнорировать; Есть гораздо лучшие способы улучшить производительность приложения, чем переключение вызовов методов на вызовы переменных.

Если вас беспокоит то, что вы не хотите набирать documents снова и снова, когда вы можете просто набрать docs, тогда используйте alias_method:

class User < ApplicationRecord
  has_many :documents
  alias_method :docs, :documents
end

Тогда нет никакой разницы между вызовами user.documents и user.docs - они вызывают один и тот же метод. Но опять же, это что-то делает для улучшения читабельности кода? На мой взгляд, нет.

Палка с вызовом documents.

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