我有一个程序,其中str.isupper()
在一个非常紧凑的循环中被调用,占用了大约25%的运行时间。
令我感到震惊的是,isupper
和islower
比其他isX
方法慢得多,例如isalnum
,isalpha
,isdigit
和等等。 (注意:在cpython中,所有方法都同样慢。)
$ pypy -mtimeit "'a'.islower()" - 0.0158 usec per loop
$ pypy -mtimeit "'a'.isalpha()" - 0.00251 usec per loop
$ pypy -mtimeit "'a'.isupper()" - 0.0164 usec per loop
$ pypy -mtimeit "'a'.isdigit()" - 0.00236 usec per loop
我可以通过
自行制作更快isupper
的方法
isupper = lambda c: 'A' <= c <= 'Z'
哪个合理0.00393 usec per loop
。当然这个版本不能为unicode字符串“工作”,但我的字符串肯定都是8bit ascii。
我的问题是,如果只使用简单的'a-z',有一种方法可以'告诉'Python跳过花哨的unicode测试吗?
答案 0 :(得分:0)
我不知道差异的原因,但我知道基准是有缺陷的。循环中的"a".islower()
这样的表达式是不变的。它完全消失了......你可能还有时间pass
。
我们可以检查"a".isalpha()
和pass
以完全相同的速度执行:它是空循环的速度。至于"a".islower()
,我不太明白,但它对我来说有时候也比较慢,有时候也不会 - 尽管它总是测量空循环的速度,因为我们可以检查(参见“jitviewer”) “如果你有兴趣的话。” CPU的奥秘?
(请注意,这是在最近的一个pypy上测量的;前一段时间islower()和isupper()遭遇缺失优化,并且没有经常折叠。)