当仅在
attrgetter('attributename')和之间
lambda o:o.attributename作为排序键进行选择时,则使用
attrgetter()是两者中 较快的 选项。
请记住,在排序之前,键函数仅对列表中的每个元素应用一次,因此,为了进行比较,我们可以在时间试用中直接使用它们:
>>> from timeit import Timer>>> from random import randint>>> from dataclasses import dataclass, field>>> @dataclass... class Foo:... bar: int = field(default_factory=lambda: randint(1, 10**6))...>>> testdata = [Foo() for _ in range(1000)]>>> def test_function(objects, key):... [key(o) for o in objects]...>>> stmt = 't(testdata, key)'>>> setup = 'from __main__ import test_function as t, testdata; '>>> tests = {... 'lambda': setup + 'key=lambda o: o.bar',... 'attrgetter': setup + 'from operator import attrgetter; key=attrgetter("bar")'... }>>> for name, tsetup in tests.items():... count, total = Timer(stmt, tsetup).autorange()... print(f"{name:>10}: {total / count * 10 ** 6:7.3f} microseconds ({count} repetitions)")... lambda: 130.495 microseconds (2000 repetitions)attrgetter: 92.850 microseconds (5000 repetitions)
因此,应用
attrgetter('bar')1000次大约比a快40μs
lambda。这是因为调用 Python
函数具有一定的开销,而不是调用诸如产生的原生函数
attrgetter()。
这种速度优势也转化为更快的排序:
>>> def test_function(objects, key):... sorted(objects, key=key)...>>> for name, tsetup in tests.items():... count, total = Timer(stmt, tsetup).autorange()... print(f"{name:>10}: {total / count * 10 ** 6:7.3f} microseconds ({count} repetitions)")... lambda: 218.715 microseconds (1000 repetitions)attrgetter: 169.064 microseconds (2000 repetitions)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)