отложенная загрузка или ранняя загрузка для python? - PullRequest
1 голос
/ 18 ноября 2009

У нас есть следующий пример кода:

big_static_data = {
  "key1" : {
     "subkey1" : "subvalue1",
     ...
     },
  "key2" : 
   ...
}
class StaticDataEarlyLoad:
    def __init__(self):
        self.static_data = big_static_data
        # other init
    def handle_use_id(self, id):
        return complex_handle(self.static_data, id)
    ...
class StaticDataLazyLoad:
    def __init__(self):
        # not init static data
        # other init
    def handle_use_id(self, id):
        return complex_handle(big_static_data, id)
    ...

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

IMO, ранняя загрузка загрузит данные при создании экземпляра и будет в памяти, пока экземпляр не будет обработан. А при поздней загрузке статические данные не будут загружаться, пока мы не вызовем метод handle_use_id . Я прав? (Так как с внутренним Python мне не очень ясно, я не уверен, как долго будет длиться экземпляр, пока он не будет облачен). И если я прав, ранняя загрузка означает большие требования к памяти, а поздняя загрузка означает, что мы должны загружать данные каждый раз при вызове метода (большие издержки?)

Теперь мы являемся веб-проектом, поэтому , который должен быть выбран в качестве наилучшего подхода? ( handle_use_id будет вызываться очень часто.)

Спасибо.

Ответы [ 2 ]

3 голосов
/ 18 ноября 2009

big_static_data создается один раз в начале файла (по крайней мере, в коде, который вы показываете).

Это потребляет память.

Когда вы создаете экземпляр StaticDataEarlyLoad,

StaticDataEarlyLoad (). Static_data является ссылкой на big_static_data. Он потребляет очень небольшое количество памяти. Он просто указывает на тот же словарь, на который указывает big_static_data. Копия big_static_data не создается, не происходит никакой "загрузки".

Когда экземпляр StaticDataEarlyLoad () получает сборщик мусора, освобождается немного памяти, но данные big_static_data остаются.

StaticDataLazyLoad делает то же самое, но не создает атрибут static_data. Он просто ссылается на big_static_data напрямую. Разница в потреблении памяти между StaticDataEarlyLoad и StaticDataLazyLoad очень незначительна. И по существу разницы в скорости не будет.

всегда лучше четко указать, от чего зависит класс. StaticDataEarlyLoad зависит от big_static_data. Следовательно, вы должны определить

class StaticDataEarlyLoad:
    def __init__(self,static_data):
        self.static_data = static_data

И инициализировать экземпляры с StaticDataEarlyLoad(big_static_data).

По сути, нет разницы в скорости между этим определением и тем, которое вы опубликовали. Поместить зависимости в сигнатуру вызова __init__ - это просто хорошая идея для организации, и в конце концов вы используете ООП Python для хорошего контроля организации, верно?

3 голосов
/ 18 ноября 2009

В вашем примере StaticDataLazyLoad (если синтаксис init правильный) не будет иметь большого значения.

"big_static_data" инициализируется ("загружается") при импорте модуля. Это немедленно потребует некоторой памяти, независимо от того, создан ли экземпляр ваших классов или нет.

Экземпляр StaticDataEarlyLoad просто создаст новую ссылку на big_static_data, а не новую копию.

Таким образом, поиск в StaticDataEarlyLoad может быть немного быстрее, поскольку на данные ссылаются через self в локальной области (поиск «self», затем поиск «self.static_data»).

Поиск в StaticDataLazyLoad не найдет "big_static_data" в локальной области видимости, затем python найдет его в глобальной области и найдет его. Поскольку глобальная область видимости, вероятно, больше, этот поиск может занять больше времени, чем поиск "self.static_data".

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