一个默认参数引发的性能问题

标签:Python, 性能

写代码时遇到个很囧的性能问题,找了几个小时才发现是默认参数引起的,然后弄了个例子来还原这个问题:
from timeit import Timer

def f(x):
  y = x
  y.append(1)
  return y

def g(x=[]):
  y = []
  y.append(1)
  return y

def h(x=[]):
  y = x
  y.append(1)
  return y

def i(x=[]):
  y = x
  if not y:
    y = []
  y.append(1)
  return y

def f2(x):
  y = x
  y.append(1)
  return y + []

def g2(x=[]):
  y = []
  y.append(1)
  return y + []

def h2(x=[]):
  y = x
  y.append(1)
  return y + []

def i2(x=[]):
  y = x
  if not y:
    y = []
  y.append(1)
  return y + []

TIMES = 10000
print Timer('f([])','from __main__ import f, g, h, i').timeit(TIMES)
print Timer('g()','from __main__ import f, g, h, i').timeit(TIMES)
print Timer('h([])','from __main__ import f, g, h, i').timeit(TIMES)
print Timer('h()','from __main__ import f, g, h, i').timeit(TIMES)
print Timer('i()','from __main__ import f, g, h, i').timeit(TIMES)
print Timer('f2([])','from __main__ import f2, g2, h2, i2').timeit(TIMES)
print Timer('g2()','from __main__ import f2, g2, h2, i2').timeit(TIMES)
print Timer('h2([])','from __main__ import f2, g2, h2, i2').timeit(TIMES)
print Timer('h2()','from __main__ import f2, g2, h2, i2').timeit(TIMES)
print Timer('i2()','from __main__ import f2, g2, h2, i2').timeit(TIMES)
我在Windows XP上用Python 2.5.4、2.6.4和3.1.1测试了,基本得到相同的结果:
0.00482128315191
0.00447319421882
0.00474278155464
0.00321605120204
0.00485899744241
0.0078350740108
0.00680449610216
0.00735959458535
0.307407785068
0.00742356919664
可以看到,h()比h([])稍快,但h2()比h2([])慢了42倍,它们的差别仅仅是是否对默认参数赋值了。而和f()、g()相比,默认参数是否赋值又并未产生什么影响。甚至i2多执行了2条语句都更快。

而把TIMES改成20000后,其他测试结果都变成2倍了,但h2()变成4倍了,这说明时间复杂度高了一倍。

不得不说Python太神奇了,这个问题我实在想不通。于是跑到Google的Python论坛提问去了,不知道有没有人能解释…

1条评论 你不来一发么↓ 顺序排列 倒序排列

    向下滚动可载入更多评论,或者点这里禁止自动加载

    想说点什么呢?