Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python扩展-高效地构造和检查大整数_Python_Python 2.7_Python 3.x_Python C Api - Fatal编程技术网

Python扩展-高效地构造和检查大整数

Python扩展-高效地构造和检查大整数,python,python-2.7,python-3.x,python-c-api,Python,Python 2.7,Python 3.x,Python C Api,我有一个本机库,对于它,自然接口将涉及传递潜在的大量数据。我预计大约一半是

我有一个本机库,对于它,自然接口将涉及传递潜在的大量数据。我预计大约一半是<32位;另四分之一<64位;下一个八分之一<128位-依此类推,没有固定的长度限制

如果我可以将值约束为适合单个寄存器,那么unsignedLonglong()的PyLong_和unsignedLonglong()的PyLong_将是合适的

PyLong_FromString()克服了这一问题,但代价是需要中间表示_PyLong_FromByteArray()和_PyLong_AsByteArray()降低了这一成本(通过简化此中间表示法),但开头的下划线让我怀疑这是否会导致可移植性问题


在longintrepr.h中,我找到了struct\u longobject。。。这暗示它可能是一种直接与内部表示交互的方式。。。尽管缺乏关于这一结构的详细文档仍然是一个障碍


什么方法可以在Python和库之间实现最佳吞吐量?有我忽略的文档吗?

听起来你需要
PyNumber\u Long
。一些文档命中率是。

下划线前缀在C API中的含义与在普通Python中的含义基本相同:“此函数是一个需要更改的实现细节,因此如果使用它,请注意自己”。您不被禁止使用此类函数,如果这是实现特定目标的唯一方法(例如,在您的情况下显著提高效率),那么只要您意识到危险,就可以使用API

如果ByteArray的
\u PyLong\u
API是真正私有的,那么它将是一个
静态
函数,不会在
longobject.h
中完整记录和导出。事实上,Tim Peters(著名的Python核心开发人员)明确表示:

[丹·克里斯滕森]

我的学生和我正在写一个C扩展,它产生一个大的 二进制中的整数,我们希望将其转换为python long。这个 位数可以远远超过32位,甚至64位。我的学生发现 longobject.h中的函数_PyLong_FromByteArray正好是 我们需要什么,但最前面的下划线让我很警惕。安全吗 使用这个功能

Python在内部使用它,所以最好是;-)

它会继续存在于python的未来版本中吗

没有保证,这就是为什么它有一个前导下划线:它不是 官方支持的、外部记录的广告内容的一部分 Python/capi。碰巧我添加了这个函数,因为 Python在内部需要某种形式的功能 不同的C模块。使其成为Python/CAPI的正式部分 会有更多的工作(我没有时间做),而且 创造了一个永恒的新维护负担(我不喜欢 不管;-))

实际上,很少有人涉及Python实现的这一部分,所以 在未来的几年里,我不会/预计/它会消失,甚至改变。 我能马上想到的最大的不安全感就是有人可能 发起一场改革,让其他字节数组成为长接口 “官方”基于表示负整数的不同方式。 但即便如此,我预计目前的非官方职能仍将保留, 因为256的补码表示对于
struct
模块的“q”格式,对于
pickle
模块的协议=2 长序列化格式

还是我们应该使用其他方法

不。这就是为什么这些函数一开始就被发明;-)

以下是文档(来自Python 3.2.1):

/*\u PyLong\u FromByteArray:将n个无符号字节作为二进制整数查看
以256为基数,并返回具有相同数值的Python long。
如果n为0,则整数为0。其他:
如果little_endian为1/true,则字节[n-1]为MSB,字节[0]为LSB;
else(little_endian为0/false)字节[0]为MSB,字节[n-1]为
LSB。
如果is_signed为0/false,则将字节视为非负整数。
如果is_signed为1/true,则将字节视为2的补码整数,
如果MSB的位0x80为空,则为非负;如果已设置,则为负。
错误返回:
+如果没有异常,则返回NULL并设置相应的异常
足够的内存来创建Python长文件。
*/
PyAPI_FUNC(PyObject*)_PyLong_from Bytearray(
常量无符号字符*字节,大小\u t n,
int小的,int是有符号的);

它是一个“下划线前缀”API的主要原因是,它依赖于Python
long
的实现,它是一个以两个基数的幂为单位的单词数组。这不太可能改变,但由于您正在实现一个API,您可以在以后将调用方与Python API中的更改隔离开来。

然后将快速API应用于足够小的数字,而“PyLong_FromString”只应用于大的数字,还是不够快?。(顺便问一下,您可能应该用
python-c-api
)分析并发现转换是一个瓶颈,还是您只是在猜测?在找到简单问题的复杂解决方案之前,请确保存在问题。我关心的是API设计阶段,而不是分析实现的结果。我正在寻找一种最简洁的方法(A)用C语言构造塔隆对象——我知道它们的长度和设置了哪些位;(B)比较和测试C中的塔隆对象中的位。涉及字符串似乎非常笨拙,我希望找到一个更简洁的解决方案。“尽管缺乏关于此结构的详细文档仍然是一个障碍”。我不知道为什么这是一个障碍。我看了看
longintrepr.h
。对于私有API,它似乎有很好的文档记录。如果您对任何事情感到困惑,可以随时查阅
longobject.c
so