您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python性能:是否尝试-否?

Python性能:是否尝试-否?

这是一个微妙的问题,因为您需要注意避免“持久的副作用”,并且性能折衷取决于丢失键的百分比。因此,请考虑以下dil.py文件

def make(percentmissing):
  global d
  d = dict.fromkeys(range(100-percentmissing), 1)

def addit(d, k):
  d[k] = k

def with_in():
  dc = d.copy()
  for k in range(100):
    if k not in dc:
      addit(dc, k)
    lc = dc[k]

def with_ex():
  dc = d.copy()
  for k in range(100):
    try: lc = dc[k]
    except KeyError:
      addit(dc, k)
      lc = dc[k]

def with_ge():
  dc = d.copy()
  for k in range(100):
    lc = dc.get(k)
    if lc is None:
      addit(dc, k)
      lc = dc[k]

以及一系列timeit呼叫,例如:

$ python -mtimeit -s'import dil; dil.make(10)' 'dil.with_in()'
10000 loops, best of 3: 28 usec per loop
$ python -mtimeit -s'import dil; dil.make(10)' 'dil.with_ex()'
10000 loops, best of 3: 41.7 usec per loop
$ python -mtimeit -s'import dil; dil.make(10)' 'dil.with_ge()'
10000 loops, best of 3: 46.6 usec per loop

这表明,缺少10%的密钥,in检查实际上是最快的方法

$ python -mtimeit -s'import dil; dil.make(1)' 'dil.with_in()'
10000 loops, best of 3: 24.6 usec per loop
$ python -mtimeit -s'import dil; dil.make(1)' 'dil.with_ex()'
10000 loops, best of 3: 23.4 usec per loop
$ python -mtimeit -s'import dil; dil.make(1)' 'dil.with_ge()'
10000 loops, best of 3: 42.7 usec per loop

仅丢失1%的密钥,该exception方法 快(get无论哪种情况,该方法仍然是最慢的一种)。

因此,为了获得最佳性能,除非 (99%以上)的查找成功,否则该in方法是可取的。

当然,还有另一种优雅的可能性:添加像…这样的dict子类:

class dd(dict):
   def __init__(self, *a, **k):
     dict.__init__(self, *a, **k)
   def __missing__(self, k):
     addit(self, k)
     return self[k]

def with_dd():
  dc = dd(d)
  for k in range(100):
    lc = dc[k]

然而…:

$ python -mtimeit -s'import dil; dil.make(1)' 'dil.with_dd()'
10000 loops, best of 3: 46.1 usec per loop
$ python -mtimeit -s'import dil; dil.make(10)' 'dil.with_dd()'
10000 loops, best of 3: 55 usec per loop

…虽然确实很漂亮,但这并不是性能上的赢家- 即便采用这种get方法,或更慢的速度,也要使用外观漂亮的代码来实现。(在defaultdict语义上类似于此类dd,如果适用的话,将是性能上的胜利,但这是因为__missing__在这种情况下,特殊方法是在经过优化的C代码中实现的)。

python 2022/1/1 18:29:01 有205人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶