【问题标题】:Difference between PyInt_FromLong and Py_BuildValuePyInt_FromLong 和 Py_BuildValue 之间的区别
【发布时间】:2013-07-14 01:36:46
【问题描述】:

Python/C API 有许多相关的函数,它们执行类似的操作,其中一个通常用于一般用途,另一个在特定情况下更有效或更方便。

例如,PyDict_SetItemPyDict_SetItemString 是相同的,但后者专门用于 C 字符串作为键。对于PyList_SetItemPyList_SET_ITEM,第二个没有错误检查,也没有对现有项目进行decref (explained here)。

但是当总是有Py_BuildValue 时,为什么会有像PyInt_FromLong 这样的特殊转换?两者都返回对 Python 对象的新引用,并且似乎做同样的事情。同样的问题也适用于 PyInt_FromSsize_tPyTuple_Pack 等函数(当然,所有这些函数都与带有适当格式字符串的 Py_BuildValue 相比)。

什么时候应该使用一个而不是另一个?

【问题讨论】:

  • 您可以查看Py_BuildValue 作为facade pattern 的结果。这是一个将许多低级调用组合在一起的高级调用。这不是必需的,但它很有用。显然,如果没有低级 API 的单个函数 Py_BuildValue,您最终将需要维护数百行或更多行代码,因此您必须反其道而行之:级转换 API 和用于高级访问的外观函数,它更短且可维护。

标签: python python-c-api python-c-extension


【解决方案1】:

对我来说,这是性能和简单性之间的权衡。对于我编写的代码,我倾向于在不关心运行时间时使用 Py_BuildValue(即返回一组不会改变的值,或者运行时间很长,额外的开销无关紧要.) 对于性能关键函数,尤其是那些可能位于循环最内层的函数,我将尽可能使用最底层的 API 调用。

是否值得是另一个问题。我永远不会收回我为获得最佳性能而花费的时间,但我知道使用我的代码的其他应用程序要快得多。

【讨论】:

  • 为什么Py_BuildValue 更简单?它需要更多的击键很长时间。如果PyInt_FromLong 更快,为什么Py_BuildValue 不直接调用呢?
  • 我只在我想创建一个元组时使用Py_BuildValue,通常作为函数的返回值,但在调用其他 C API 函数时也是如此。从性能关键函数返回元组时,我实际上会创建一个空元组,然后设置元组值。这比调用Py_BuildValue("(NN)",...) 更快,但需要更多的代码行。当只创建一个值时,我总是直接使用低级函数。 Py_BuildValue 确实调用了PyInt_FromLong,但它必须先解析字符串,检查需要多少个值等。速度稍慢。
  • 谢谢。您的评论以及 Bakuriu 的评论是我正在寻找的真正答案,但我仍会将其标记为正确答案。
猜你喜欢
  • 1970-01-01
  • 2021-12-25
  • 2020-05-10
  • 2014-09-20
  • 2010-10-28
  • 2015-10-04
  • 2012-08-12
  • 2011-02-18
  • 2019-12-21
相关资源
最近更新 更多