aSt*_*eve 10 python python-c-api python-2.7 python-3.x
我有一个本地库,其自然界面将涉及传递可能大的数字.我预计大约一半是<32位; 另一季度<64位; 接下来的第八个<128位 - 依此类推,没有固定的长度限制.
如果我可以约束值以适合单个寄存器,那么PyLong_FromUnsignedLongLong()和PyLong_AsUnsignedLongLong()将是合适的.
PyLong_FromString()克服了这一点 - 但需要中间表示的不必要的代价._PyLong_FromByteArray()和_PyLong_AsByteArray()减轻了这个成本(通过简化这个中间表示),但是前导下划线让我想知道这是否会导致可移植性问题.
在longintrepr.h中,我发现了struct _longobject ...它暗示它可能是一种直接与内部表示交互的方式......虽然没有关于这种结构的详细文档仍然是一个障碍.
什么方法将导致Python和库之间的最佳吞吐量?有没有我忽略过的文件?
下划线前缀在很大程度上意味着C API与普通Python中的相同:"这个函数是一个可以改变的实现细节,所以如果你使用它就要注意自己".您不被禁止使用此类功能,如果这是实现特定目标的唯一方法(例如,在您的情况下显着提高效率),那么只要您意识到危险,就可以使用API.
如果_PyLong_FromByteArrayAPI是真正私有的,那么它将是一个static函数,并且不会完全记录并导出longobject.h.事实上,Tim Peters(一位着名的Python核心开发人员)明确祝福它的用途:
[Dan Christensen]
我的学生和我正在编写一个C扩展,它生成一个二进制的大整数,我们想要转换为python long.位数可以超过32或甚至64.我的学生在longobject.h中找到了函数_PyLong_FromByteArray,这正是我们所需要的,但是领先的下划线让我很谨慎.使用此功能是否安全?
Python在内部使用它,所以最好是;-)
它将继续存在于未来的python版本中吗?
没有保证,这就是为什么它有一个领先的下划线:它不是官方支持的,外部记录的,是宣传的Python/C API的一部分.碰巧我添加了这个函数,因为Python在不同的C模块内部需要某种形式的功能.将它作为Python/C API的官方部分将会有更多的工作(我没有时间),并创造了一个永恒的新维护负担(我不喜欢这个;-)).
在实践中,很少有人触及Python实现的一部分,所以我不/希望/它会消失,甚至改变,几年来.我可以想到的最大的不安全感是有人可能会发起一个十字军东征,根据表示负整数的不同方式,制作一些其他字节数组< - >长接口"官方".但即便如此,我仍然希望保留当前的非官方函数,因为256的补码表示仍然是
struct模块的"q"格式所必需 的,对于pickle模块的协议= 2长序列化格式也是如此.或者我们应该使用其他方法吗?
不,这就是为什么这些功能一开始就被发明的原因;-)
这是文档(来自Python 3.2.1):
/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
base 256, and return a Python long with the same numeric value.
If n is 0, the integer is 0. Else:
If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
LSB.
If is_signed is 0/false, view the bytes as a non-negative integer.
If is_signed is 1/true, view the bytes as a 2's-complement integer,
non-negative if bit 0x80 of the MSB is clear, negative if set.
Error returns:
+ Return NULL with the appropriate exception set if there's not
enough memory to create the Python long.
*/
PyAPI_FUNC(PyObject *) _PyLong_FromByteArray(
const unsigned char* bytes, size_t n,
int little_endian, int is_signed);
Run Code Online (Sandbox Code Playgroud)
它是"下划线前缀"API的主要原因是因为它依赖于Python的实现long作为二次幂基础中的单词数组.这可能不会改变,但由于您在此基础上实现了API,因此您可以在稍后将调用者与Python API中的更改隔离开来.
| 归档时间: |
|
| 查看次数: |
700 次 |
| 最近记录: |