23[us] spent in [py2] to process ( x in range( 10E+0000 ) )
4[us] spent in [py2] to process ( x in range( 10E+0001 ) )
3[us] spent in [py2] to process ( x in range( 10E+0002 ) )
37[us] spent in [py2] to process ( x in range( 10E+0003 ) )
404[us] spent in [py2] to process ( x in range( 10E+0004 ) )
4433[us] spent in [py2] to process ( x in range( 10E+0005 ) )
45972[us] spent in [py2] to process ( x in range( 10E+0006 ) )
490026[us] spent in [py2] to process ( x in range( 10E+0007 ) )
2735056[us] spent in [py2] to process ( x in range( 10E+0008 ) )
MemoryError
in range( a ) 构造函数的语法不仅在 [TIME] 域中是 slow,而且具有 --at best-- O (log N),如果做得更聪明,比通过列表值的枚举域进行纯顺序搜索,但是
在
py2,本机 range() 总是有一个复合附加组件 O( N ) 成本,即 [TIME] 域成本(构建时间)和这种基于 range 的内存的 [SPACE] 域成本(分配存储空间 + 花费更多时间将所有这些数据通过...) - 表示构造。
让我们对安全的O( 1 ) 规模化方法进行基准测试(+总是做基准测试)
>>> from zmq import Stopwatch
>>> aClk = Stopwatch()
>>> a = 123456789; x = 123456; aClk.start(); _ = ( 0 <= x < a );aClk.stop()
4L
>>> a = 123456789; x = 123456; aClk.start(); _ = ( 0 <= x < a );aClk.stop()
3L
评估基于条件的公式需要 3 ~ 4 [us],具有 O(1) 缩放,对于 x 量级不变。
接下来,使用 x in range( a ) 公式进行测试:
>>> a = 123456789; x = 123456; aClk.start(); _ = ( x in range( a ) );aClk.stop()
并且您的机器几乎会在内存吞吐量受限的 CPU 饥饿中死机(更不用说从一些 ~ 100 [ns] 成本范围到一些 @ 987654340@ 交换磁盘 IO 数据流的成本)。
不,不,不。永远无法测试 x 是否在有界范围内。
创建其他基于类的评估器的想法,仍然通过枚举( set )解决问题将永远无法满足基准 3 ~ 4 [us] (如果不使用一些超出我对经典和量子物理学因果定律的理解的外星魔法)
Python 3 has changed the way, how the range()-constructor works,但这不是原帖的核心价值:
3 [us] spent in [py3] to process ( x in range( 10E+0000 ) )
2 [us] spent in [py3] to process ( x in range( 10E+0001 ) )
1 [us] spent in [py3] to process ( x in range( 10E+0002 ) )
2 [us] spent in [py3] to process ( x in range( 10E+0003 ) )
1 [us] spent in [py3] to process ( x in range( 10E+0004 ) )
1 [us] spent in [py3] to process ( x in range( 10E+0005 ) )
1 [us] spent in [py3] to process ( x in range( 10E+0006 ) )
1 [us] spent in [py3] to process ( x in range( 10E+0007 ) )
1 [us] spent in [py3] to process ( x in range( 10E+0008 ) )
1 [us] spent in [py3] to process ( x in range( 10E+0009 ) )
2 [us] spent in [py3] to process ( x in range( 10E+0010 ) )
1 [us] spent in [py3] to process ( x in range( 10E+0011 ) )
在 Python 2 中,range() 和 xrange() 都没有摆脱 O( N ) 缩放的陷阱,其中 xrange()-generator 的运行速度似乎只有 2x 慢
>>> from zmq import Stopwatch
>>> aClk = Stopwatch()
>>> for expo in xrange( 8 ):
... a = int( 10**expo); x = a-2; aClk.start(); _ = ( x in range( a ) );aClk.stop()
...
3L
8L
5L
40L
337L
3787L
40466L
401572L
>>> for expo in xrange( 8 ):
... a = int( 10**expo); x = a-2; aClk.start(); _ = ( x in xrange( a ) );aClk.stop()
...
3L
10L
7L
77L
271L
2772L
28338L
280464L
范围边界语法享有 ~ < 1 [us] 的 O( 1 ) 恒定时间,如上所示,因此设置了再次比较的标准:
>>> for expo in xrange( 8 ):
... a = int( 10**expo); x = a-2; aClk.start(); _ = ( 0 <= x < a );aClk.stop()
...
2L
0L
1L
0L
0L
1L
0L
1L