为尾随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 Hibernate在实体映射中出现重复列   java如何用FTP目录填充JTree?   java无法解析引用本地ejbref。两个EJB模块之间的通信   java如何在主文件夹的文件和子文件夹中进行更改?   java如何在接到电话时“正确”发送短信?   java有没有一种方法可以在javafx的桌面浏览器中使用saml对用户进行身份验证   java如何通过命令行开始在eclipse中运行?   带有远程数据库的java安卓应用程序   java替换行输入。基于关闭标志的txt文件   爪哇科特林。如何将十进制数的结尾设置为零?   java AgentInitializationException:已加载代理JAR,但代理在尝试注入JAR文件时未能初始化   Java:nextInt()验证不起作用   垃圾收集使用Java9G1GC,系统。应用程序加载时未执行gc()。为什么?   java将Spring引导应用程序部署到Tomcat服务器   java在创建新方法的同时创建新对象,这怎么可能呢?   使用HFileOutputFormat2时发生java ClassCastException   java应用程序未从编辑文本中获取值,似乎正在跳过行