延迟加载或早期加载python?

时间:2009-11-18 14:14:15

标签: python performance

我们有以下代码示例:

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 个答案:

答案 0 :(得分:3)

在您的示例中,StaticDataLazyLoad(一旦 init 的语法正确)将不会产生重大影响。

导入模块时,

“big_static_data”被初始化(“加载”)。无论是否创建了类的实例,它都会立即需要一些内存。

StaticDataEarlyLoad的实例只会创建对big_static_data的新引用,而不是新副本。

因此,StaticDataEarlyLoad中的查找可能会稍快一些,因为数据是通过本地范围内的self引用的(查找“self”,然后查找“self.static_data”)。

StaticDataLazyLoad中的查找在本地范围内找不到“big_static_data”,然后python将在全局范围内查找并找到它。由于全局范围可能更大,因此查找可能需要比查找“self.static_data”更长的时间。

答案 1 :(得分:3)

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的OOP来很好地控制组织,对吧?