【问题标题】:Python list.clear complexity [duplicate]Python list.clear复杂性[重复]
【发布时间】: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 会在后台进行删除(我不确定这个信息),所以我不会加快应用上述任何方法的速度,因为结果是相同的。

感谢任何知识。谢谢。

【问题讨论】:

    标签: python python-3.x time-complexity


    【解决方案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)。

    【讨论】:

      猜你喜欢
      • 2020-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 1970-01-01
      相关资源
      最近更新 更多