Python:分配变量和调用方法的内存效率

时间:2014-07-29 19:03:50

标签: python memory

这一直困扰着我。我想知道分配变量和调用方法的比较内存效率。例如,考虑一下:

  

s =" foo"
  x = s.lower()

对战

  

x =" foo" .lower()

在内存使用方面哪一个更有效?

这显然是一个微不足道的例子,但它说明了我对此感到疑惑 我们在很多实例中定义了一些变量var1 = foo,然后定义了第二个变量var2 = var1.method()。整个过程是否需要更多内存而不仅仅是定义var2 = foo.method()

2 个答案:

答案 0 :(得分:2)

第一种情况下字节码较大,但只有很少的数量。

$ python3
Python 3.3.5 (default, Mar  9 2014, 08:10:50) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dis
>>> def f():
...   s = "foo"
...   x = s.lower()
...   return x
... 
>>> def g():
...   x = "foo".lower()
...   return x
... 
>>> dis.dis(f)
  2           0 LOAD_CONST               1 ('foo') 
              3 STORE_FAST               0 (s) 

  3           6 LOAD_FAST                0 (s) 
              9 LOAD_ATTR                0 (lower) 
             12 CALL_FUNCTION            0 (0 positional, 0 keyword pair) 
             15 STORE_FAST               1 (x) 

  4          18 LOAD_FAST                1 (x) 
             21 RETURN_VALUE         
>>> dis.dis(g)
  2           0 LOAD_CONST               1 ('foo') 
              3 LOAD_ATTR                0 (lower) 
              6 CALL_FUNCTION            0 (0 positional, 0 keyword pair) 
              9 STORE_FAST               0 (x) 

  3          12 LOAD_FAST                0 (x) 
             15 RETURN_VALUE         
>>> 

(令人遗憾的是,CPython 仍然在字节编译时甚至没有做基本的CSE或copyprop,但这是一个完整的问题。 。)

在第一种情况下,运行时内存要求也略大,因为该函数有两个可变插槽而不是一个,但字符串本身不会复制额外的时间。 Python始终如一地使用引用语义。

编辑:正如cdonts指出的那样,如果代码更复杂且变量不会立即超出范围,则第一个版本会保持原始字符串在堆上保持活动状态,直到{ {1}}超出了范围, 可能是一个重要的额外内存成本。我甚至都没有想到这一点。

答案 1 :(得分:1)

在您的第一个示例中,s仍在内存中,直到垃圾收集器删除它,因此您的第二个示例在内存使用方面更有效。但是,考虑到这只是RAM的一小部分,在许多情况下最好是为了提高可读性(第一个例子看起来更好)。

希望这有帮助。