Aar*_*ron 4 python python-c-extension
我需要用 C 语言编写一个 Python 扩展,我将用它来:
一种解决方案是在 Python 中实现“状态持有者”类。当我在 C 中调用初始化时,它返回我将存储在 Python 状态对象中的初始化数据。然后每次我需要执行步骤 (2) 时,我都会将其传递给 C 函数。但是,对于 Python 端和 C 端之间发生的所有数据穿梭/接口来说,这似乎非常低效。
如果可能的话,我想在 C 端使用状态对象来维护状态。来自 Python 端的初始化调用不会返回所有初始化数据,而仅返回一个 ID,以便在后续调用期间需要时可以引用 C 状态对象。
我将如何维护 C 端的状态?
首先,我将回答您实际提出的问题。
\n\n在 C 中创建一个struct State,就像不涉及 Python 时一样。
如果你不打算复制这些(你只是传递它们struct State *),那么你可以获取(intptr_t)theStatePtrPython 的 id。当然,您确实需要小心,Python 对象的生命周期永远不会超过 C 对象的生命周期,但这是可行的。
如果出于某种原因确实需要复制/移动结构,或者需要更多帮助来管理状态(例如,将 Python id 视为弱引用),请选择适当的集合(哈希表、树、数组等)您的用例,然后将密钥作为 id 传递给 Python。
\n\n但是,我认为您可能在这里优化了错误的部分。来回传递对象没什么意义\xe2\x80\x94,它只是一个指针副本。重新计数可能是一个问题,但很少是问题,并且从生命周期管理中获得的好处通常是值得的。可能会降低性能的部分是你的 C 代码不断地将一堆 Python 整数转换为 Cint等。如果这是你的问题,只需创建一个具有 C 状态的 C 结构体,并将其包装在一个不存在的 Python 对象中。不要将任何内部结构公开到 Python 中。
最后,你真的需要任何优化吗?如果您正在进行 CPU 密集型工作,我敢打赌,实际工作会完全掩盖 Python 对象访问的成本,以至于后者甚至不会出现在分析中。如果您还没有进行分析,那么这绝对是您应该做的第一件事,因为这里的正确答案很可能是“不要费心做任何事情”。
\n\n更进一步:如果您只是用 C 语言编写 C 代码以进行优化,您确定需要这样做吗?在 C 中处理内存管理是烦人且容易出错的,在 Python 的 C 扩展模块中处理它更是如此,当你还不知道它是如何工作的时候第一次这样做几乎是一个保证的秘诀将所有时间都花在查找段错误和泄漏上,而不是编写实际的代码。因此,我会按顺序尝试以下操作,对每个操作进行分析,并且仅在速度太慢时才在列表中向下移动:
\n\nctypes.