Python bool()和operator.truth()之间有什么区别?
这两种方法都测试一个值是真的还是假的,它们在文档中看起来非常相似,甚至在Python bool()和operator.truth()之间有什么区别?,python,python-3.x,python-2.7,performance,boolean,Python,Python 3.x,Python 2.7,Performance,Boolean,这两种方法都测试一个值是真的还是假的,它们在文档中看起来非常相似,甚至在truth()文档中说: 这相当于使用bool构造函数 但是,从一个简单的测试来看,truth()的速度是bool()的两倍多(显示了Python 3.6计时,但2.7类似): 那么有什么区别呢?我应该使用truth()而不是bool() 虽然bool()和operator.truth()在主要用例中输出相同的结果,但它们的实现实际上是相当不同的,但在与under.进行了广泛的评论和讨论后,出现了此问答bool()是一个类或
truth()
文档中说:
这相当于使用bool构造函数
但是,从一个简单的测试来看,truth()
的速度是bool()
的两倍多(显示了Python 3.6计时,但2.7类似):
那么有什么区别呢?我应该使用truth()
而不是bool()
虽然bool()
和operator.truth()
在主要用例中输出相同的结果,但它们的实现实际上是相当不同的,但在与under.进行了广泛的评论和讨论后,出现了此问答bool()
是一个类或类型构造函数,而truth()
是一个狭义的优化正则函数
实际上,还有两个区别:1)bool()
调用时不带参数return
sFalse
,而truth()
需要参数。2) bool()
接受x
关键字参数,如bool(x=1)
,而truth()
不接受关键字参数。对于常规用例,这两种方法都会增加bool()
的开销
关键字implementation很奇怪,因为可能没有人需要它,而且名称x
几乎没有描述性。涵盖了这一点,事实上,该问题不仅影响bool()
,还影响其他类,如int()
或list()
。但是,从Python3.7开始,这些关键字参数将被删除,速度应该会提高。尽管如此,我还是在最新的Python3.8分支上测试了计时,并且bool()
比以前快,但仍然比truth()
慢两倍多,这可能是因为bool()
的实现更加通用
因此,如果您有一项速度非常重要的任务,我建议您在需要函数时使用truth()
而不是bool()
(例如解析为sorted()
的键)。然而,正如所指出的,bool()
有时仍然会更快,例如filter(bool,iterable)
,因此最好对用例进行计时,以确定最佳选项
当然,如果您不需要函数,只是想测试一个值是真是假,那么您应该使用惯用的if
或if not
语句,这两个语句最快,如khelwood和注释所示
这一问答是在与under进行了广泛的评论和讨论后产生的。
timeit('b(1)','b=bool')
明显快于timeit('bool(1))
(尽管仍然比truth
慢得多)。查找全局名称bool
会影响结果。@khelwood谢谢,说得好,但时差仍然超过两倍,是吗?是的,truth
肯定比bool
快得多(顺便说一句,如果……否则False)比True慢得多。@khelwood Yep,我猜if
语句是高度优化的;truth
的用例是解析关键字参数,如key=bool
如果你在进行微优化,考虑到bool
的成本,最好只使用而不是x
而不是truth(x)
@user2357112,这是速度的一半,所以有时候可能不仅仅是微观优化?但是,是的,它产生的背景是作为一个关键功能(对于itertools.groupby)
而且,我认为filter
可能会特别优化,以适应将bool
传递给它的情况。@Chris_Rands我对这方面的知识基本上仅限于我已经说过的内容。=)如果答案有用的话,请随意将其包含在你的答案中。@khelwood:是的,(它不是实际调用回调,而是直接调用PyObject\u IsTrue
)。因此,例外情况是根本不调用bool
;如果实际调用了bool
,它总是比等价的truth
慢。在AICT中,识别这种情况的唯一其他函数是itertools.filterfalse
;所有其他itertools
(例如takewhile
/dropwhile
)不提供这种特殊情况。
from timeit import timeit
print(timeit('bool(1)', number=10000000))
# 2.180289956042543
print(timeit('truth(1)', setup='from operator import truth', number=10000000))
# 0.7202018899843097