Python 用于打印进度的有效可分性检查
在我的程序中,当我觉得需要很长时间时,我会执行一个进度检查:我使用0的模(Python 用于打印进度的有效可分性检查,python,modulo,Python,Modulo,在我的程序中,当我觉得需要很长时间时,我会执行一个进度检查:我使用0的模(如果I%n==0…)打印迭代器的当前值和每n次迭代的时间差 Python解释器(或任何其他编程语言编译器)是否有效地检查2的幂的可除性?就像取最后一个(幂)位并检查所有值是否都等于0一样?Python中任何整数运算的效率充其量都是值得怀疑的。除了解释器开销外,您还需要处理整数是可变精度的事实,这需要对每个操作进行更多处理 也就是说,您可以使用位旋转来检查2次方的可整除性。对于给定的n,您可以 p = (1 <<
如果I%n==0…
)打印迭代器的当前值和每n次迭代的时间差
Python解释器(或任何其他编程语言编译器)是否有效地检查2的幂的可除性?就像取最后一个(幂)位并检查所有值是否都等于0一样?Python中任何整数运算的效率充其量都是值得怀疑的。除了解释器开销外,您还需要处理整数是可变精度的事实,这需要对每个操作进行更多处理 也就是说,您可以使用位旋转来检查2次方的可整除性。对于给定的
n
,您可以
p = (1 << n) - 1 # n of your choice
...
if not i & p:
...
p=(1查看以下lambda的格式化字节码,CPython中的字节码级别似乎没有任何差异:
In [1]: import dis
In [2]: dis.dis(lambda x: x % 3 == 0)
1 0 LOAD_FAST 0 (x)
2 LOAD_CONST 1 (3)
4 BINARY_MODULO
6 LOAD_CONST 2 (0)
8 COMPARE_OP 2 (==)
10 RETURN_VALUE
In [3]: dis.dis(lambda x: x % 2 == 0)
1 0 LOAD_FAST 0 (x)
2 LOAD_CONST 1 (2)
4 BINARY_MODULO
6 LOAD_CONST 2 (0)
8 COMPARE_OP 2 (==)
10 RETURN_VALUE
In [4]:
二进制_模(取2个参数的模运算,因此为“二进制”)最终由Objects/longobject.c
中的long_mod
函数在CPython中处理(对于2个整数,也称为“longs”)
通过浏览代码,对于操作数只有一个位数的情况,似乎有一些初始优化
如果没有,则最终会调用包含以下注释的x_divrem
:
/* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd
edn.), section 4.3.1, Algorithm D], except that we don't explicitly
handle the special case when the initial estimate q for a quotient
digit is >= PyLong_BASE: the max value for q is PyLong_BASE+1, and
that won't overflow a digit. */
我真的不想花时间去理解代码中的算法(我没有提到这本书),但通过略读,它看起来像是在执行一些巧妙的位移位操作。我打赌,在除数是2的幂的情况下,这个算法会运行得更快。不过,还不能完全确定
您可以在这里查看:
我可以向您保证,单模运算并不是程序中的瓶颈。在出现问题时,请尽量只考虑性能。此外,在PythonKeep中,检查模运算的速度非常快。在Python中,打印通常非常慢,尤其是“我觉得”不是找到性能不佳原因的良好基础。您是否尝试过使用探查器?我认为OP只是想要一些进度指示,而不是试图找到加速循环的方法。这似乎比较慢。我做了一次timeit,大约用了73纳秒,而not I%m
大约用了55纳秒。@HeapOverflow。我一点也不奇怪。整数运算的瓶颈是循环,它跨越了无限精度的整数数据,而不是运算本身。您是否将时间以ns为算术平均值?以ns为单位进行测量似乎更像是一个测量错误。@Ferazhu我没有做任何不寻常的事情。例如,我运行了python-m timeit-s“i=1000;p=4095”“不是i&p”
,它报告了5000000个循环,每个循环的最佳值为5:71.4nsec
@madpysicator不确定你的意思,但是python-m timeit“对于范围内的i(10**6):pass”
表示31毫秒,而python-m timeit-s“p=4095”表示范围内的i(10**6):不是i&p“
表示92毫秒。因此,在这种情况下,循环/步进似乎不是瓶颈。