为尾随0位的模实现更快的divmod()

shift-divmod的Python项目详细描述


Info:This is the README file for ShiftDivMod.
Author:Shlomi Fish <shlomif@cpan.org>
Copyright:© 2020, Shlomi Fish.
Date:2020-09-20
Version:0.4.3
https://travis-ci.org/shlomif/shift_divmod.svg?branch=master

目的

这个发行版实现了更快的divmod()(和.mod())操作 对于有大量尾随0位的模(其中div/mod基 对于整数n,可以被2 ** n整除。在

它应该产生与内置的divmod()函数相同的结果 正分子(它对负分子的行为目前是 未测试和未定义)。在

还提供了到C和gmplib(=GNU多精度)的端口: https://github.com/shlomif/shift_divmod/tree/master/gmp-shift_divmod

安装

pip3安装shift_divmod

使用

from shift_divmod import ShiftDivMod

base = 997
shift = 1200
modder = ShiftDivMod(base, shift)
# Alternative constructor which may require more
# work and eventualy calls the default constructor
modder = ShiftDivMod.from_int(base << shift)

x = 10 ** 500
# Same as divmod(x, (base << shift))
print( modder.divmod(x) )

注释

从中派生出此分布的代码被建议为 内置cpython3潜在改进的概念证明 此处的操作:https://bugs.python.org/issue41487。但是,更改cpython3 就这样被拒绝了。在

libdivide(https://github.com/ridiculousfish/libdivide)提供了一个 不同的,但也很有趣的优化划分的方法。在

基准:

在我的系统上,我在运行后得到了这些结果 python3 code/examples/shift_divmod_example.py bench(已重新格式化 为清楚起见):

^{pr2}$

可以注意到,基于shift_divmod的版本比 它比只完成1000次迭代中的25次的内置nops快得多 在被打断之前。注意,对于这个用例,使用GMP的模幂 似乎更快。在

对于C和gmplib版本:

  • mpz_mod运行基准测试大约需要160秒。在
  • shift_divmod运行基准测试大约需要35秒。在
  • pypy3在25秒内运行纯Python代码(!)。在

秘方:

代码利用了bitwise operations 速度很快,这段代码中出现了神奇的效果(为了清晰起见,添加了一些注释):

# Precalculating the object's field so that:
# self.shift : a non-negative integer signifying the bit shift
# self.base  : a non-negative integer which is shifted to
# form the modulu
# self.n = self.base << self.shift
# self.mask = ((1 << self.shift) - 1)
def divmod(self, inp):
    """calculate divmod(inp, self.n)"""
    if inp < self.n:
        return 0, inp
    div, mod = divmod((inp >> self.shift), self.base)
    return div, ((mod << self.shift) | (inp & self.mask))

(或等效但更官僚的C和gmplib代码。)

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
要应用于列表的java JSTL if条件   追加文件会导致覆盖(Java)   当我使用自定义适配器和json时,java应用程序崩溃   如何在java中提取数字和字符串   Web视图中的java上传文件   安卓错误:org。json。JSONEXception:java类型的值访问。无法将lang.String转换为JSONObject   javascript如何使用appium驱动程序按id滚动到元素   用Java计算Excel列中的重复行数   垃圾收集为什么Java堆的最大大小是固定的?   java执行maven插件的目标取决于另一个插件正在执行的目标   java无法在tomcat中加载静态文件   稍后访问时,java servlet页面显示为空   JavaWebSphereApplicationServer:EJB模块和JMS路由器   Oracle:如何查看JavaEE6应用程序运行的查询?