Python list.clear复杂性[重复]
Posted
技术标签:
【中文标题】Python list.clear复杂性[重复]【英文标题】:Python list.clear complexity [duplicate] 【发布时间】:2018-04-09 16:12:51 【问题描述】:Python 3 方法list.clear()
的复杂度是多少?
这里没有给出:https://wiki.python.org/moin/TimeComplexity
在documentation里面据说和del
a[:]
是等价的,但是不知道这个函数本身的复杂度。是
是O(n)
还是O(1)
?
我查看了listobject.c
。找到了这个。
int
PyList_ClearFreeList(void)
PyListObject *op;
int ret = numfree;
while (numfree)
op = free_list[--numfree];
assert(PyList_CheckExact(op));
PyObject_GC_Del(op);
return ret;
这里看起来像O(n)
,但我不确定这是否是正确的代码。
我正在开发一个具有性能需求的程序,其中一个列表被反复填充和清空,我试图找到清空它的最佳方法(因为只有一种方法可以填充它) .
如果这个函数是O(n)
,我就每次创建一个新列表,这有它自己的成本,但我不知道更好的方法。
我想到的另一个问题是 Python 有一个垃圾收集器,所以如果我不释放这些对象(每次都创建新列表,通过重新分配变量名让另一个无人看管),Python 会在后台进行删除(我不确定这个信息),所以我不会加快应用上述任何方法的速度,因为结果是相同的。
感谢任何知识。谢谢。
【问题讨论】:
【参考方案1】:您找到的函数与 Python 中的list.clear()
无关。你需要的是_list_clear(PyListObject *a)
,可以找到here。
因此,如果您查看该方法的实现,它看起来如下:
...
static int
_list_clear(PyListObject *a)
Py_ssize_t i;
PyObject **item = a->ob_item;
if (item != NULL)
/* Because XDECREF can recursively invoke operations on
this list, we make it empty first. */
i = Py_SIZE(a);
Py_SIZE(a) = 0;
a->ob_item = NULL;
a->allocated = 0;
while (--i >= 0)
Py_XDECREF(item[i]);
PyMem_FREE(item);
/* Never fails; the return value can be ignored.
Note that there is no guarantee that the list is actually empty
at this point, because XDECREF may have populated it again! */
return 0;
...
但是,最重要的几行是您要检索列表大小的行:
i = Py_SIZE(a);
还有那些,你正在删除一个元素:
...
while (--i >= 0)
Py_XDECREF(item[i]);
...
由于Py_XDECREF
的性能不依赖于列表的大小,我们可以将其视为常数或 O(1)。由于Py_XDECREF
被称为list times的大小,所以整体的时间复杂度是线性的,所以_list_clear
的时间复杂度是O(n)。
正如@superb rain 所指出的,Py_XDECREF
对于某些元素可能会变得相当“沉重”(由于可能的递归调用),虽然它与输入大小没有直接关系,但我们可以通过引入参数e
- 减少元素引用计数的总成本。在这种解释中,总时间复杂度为 O(n+e)。
【讨论】:
以上是关于Python list.clear复杂性[重复]的主要内容,如果未能解决你的问题,请参考以下文章