使用pythoncapi将Python中的函数移植到C时出现问题

2024-04-25 14:18:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python中有一个校验和函数:

def checksum(data):
    a = b = 0
    l = len(data)
    for i in range(l):
        a += ord(data[i])
        b += (l - i)*ord(data[i])

    return (b << 16) | a, a, b

我正试图连接到一个C模块以提高速度。以下是C函数:

^{pr2}$

我通过打开一个文件并输入4096个数据块来使用它。对于小字符串,它们都返回相同的值,但是当我直接从文件中输入二进制数据时,C版本返回的值大不相同。任何帮助都将不胜感激。在


Tags: 模块数据函数infordatalenreturn
2条回答

我建议原来的校验和函数是“不正确的”。为checksum返回的值大小不受限制(对于任何给定的大小(以MB为单位),您可以构造一个输入,其校验和大小至少为这个大小)。如果我的计算是正确的,对于小于260MB的输入,该值可以容纳64位,而对于小于4096个字节的输入,b可以容纳一个整数。现在,我可能不再讨论这个数字,但这意味着对于更大的输入,这两个函数的工作方式肯定是不同的。在

要将第一个函数转换为C,需要在Python整数中保留b和{},并将最后一个计算作为Python表达式执行。不过,这一点还可以改进:

  • 您可以使用Clong long变量存储一个中间和,并在经过一定次数的迭代后将其添加到Python整数中。如果迭代次数是n,那么a的最大值是n * 255,而{}的最大值是len(data) * n * 255。当将它们存储在Clong long变量中时,请尝试将它们保存在2**63-1下。在
  • 您可以使用long long而不是unsigned long long,并且在调试模式下,每当RuntimeError为负值时,都会引发它。在

另一个解决方案是通过使用a & 0xffffffffffffffffb & 0xffffffffffffffff将Python等效值限制为64位。在

最好的解决方案是使用另一种校验和,比如binascii.crc32。在

我猜你的局部变量有某种溢出。可能b变大了。只是为了调试目的而转储这些值,然后您应该看看是否是问题所在。正如您所提到的,您移植方法是出于性能的考虑。你检查过心理科吗?可能够快也容易得多。还有更多的其他工具可以将python代码的一部分实时编译成C语言,但我脑子里没有这些名字。在

相关问题 更多 >