最近在看 Python epoll howto
的时候,发现里面对比一个 event 是不是某种 EVENT 类型用的是 &
操作符,比如 elif event & select.EPOLLIN
。一开始还以为是写错了,后来想了一下这样确实能起到 ==
的作用,只要事件的实际数字值特殊设计的话。
只比较相等的话,只要不存在包含关系就可以。比如最简单的,每一个 bit 的1表示一个类型(这里都以一个 bytes 作例子吧。
上面4个数字分别是1,2,4,8,分别可以表示四种类型。对比的时候,除非两个类型相等,否则都是 0(Flase)。或者可以用下面这种方式,使用两个1,可以表示的类型多一些。
上面这种也可以达到类似的效果。如果存在包含关系的话就不行了,在不相等的情况下依然可能得到非0值。但是如果不是比较相等的情况,而是比较是不是包含,就可以使用这种表示了。比如 Unix 的文件权限系统,用 4 2 1 来表示执行:
00000100 -------读
00000010 -------写
00000001 -------执行
如果验证 6 是否有读权限的话也可以用 &
:
00000110 -------6的表示
00000100 -------4写权限的表示
结果是非0值,表示拥有此权限。
为什么这么写呢,估计是C程序的风格吧,我用 Python 测试了一下性能, &
操作是比 ==
效率高的。因为 epoll 这部分的代码是非常频繁的操作,能节省一些性能的话,还是很可观的。
➜ [py37] tmp python -m timeit '1 == 4; 4 == 8; 8 == 16; 1 == 16'
5000000 loops, best of 5: 95.6 nsec per loop
➜ [py37] tmp python -m timeit '1 & 4; 4& 8; 8& 16; 1& 16'
50000000 loops, best of 5: 8.17 nsec per loop
➜ [py37] tmp python -m timeit '1 is 4; 4 is 8; 8 is 16; 1 is 16'
5000000 loops, best of 5: 52.4 nsec per loop
通过反编译发现,其实 &
编译成 Python 字节码是 BINARY_AND ,而 ==
是 COMPARE_OP。应该是 BINARY_AND 效率会比 COMPARE_OP 效率高一些吧。
➜ [py37] tmp ipython
Python 3.7.0 (default, Jul 7 2018, 19:33:03)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from dis import dis
In [2]: a, b = 1, 4
In [3]: def compare1():
...: a & b
...: a == b
...:
In [4]: dis (compare1)
2 0 LOAD_GLOBAL 0 (a)
2 LOAD_GLOBAL 1 (b)
4 BINARY_AND
6 POP_TOP
3 8 LOAD_GLOBAL 0 (a)
10 LOAD_GLOBAL 1 (b)
12 COMPARE_OP 2 (==)
14 POP_TOP
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
注意:本文来自卡瓦邦噶!。本站无法对本文内容的真实性、完整性、及时性、原创性提供任何保证,请您自行验证核实并承担相关的风险与后果!
CoLaBug.com遵循[CC BY-SA 4.0]分享并保持客观立场,本站不承担此类作品侵权行为的直接责任及连带责任。您有版权、意见、投诉等问题,请通过[eMail]联系我们处理,如需商业授权请联系原作者/原网站。