Какова сложность исполнения Python deepcopy ()? - PullRequest
2 голосов
/ 22 января 2012

Я пытаюсь повысить скорость работы алгоритма и, посмотрев, какие операции вызываются, мне трудно точно определить, что замедляет процесс.Я задаюсь вопросом, может ли Deepcopy () Python может быть виновником или я должен немного углубиться в свой собственный код.

Ответы [ 3 ]

3 голосов
/ 05 августа 2012

Глядя на код (вы тоже можете), он просматривает каждый объект в дереве ссылочных объектов (например, ключи и значения dict, переменные-члены объекта, ...) и выполняет для них две вещи:

  1. посмотреть, если оно уже было скопировано, посмотрев его в id-indexed memo dict
  2. копию объекта, если не

Второй - O (1) для простых объектов.Для составных объектов одна и та же процедура обрабатывает их, поэтому для всех n объектов в дереве это O (n) .Первая часть, ищущая объект в диктовке, в среднем O (1) , но O (n) амортизированный наихудший случай .

Так что в лучшем случае в среднем deepcopy является линейным.Ключи, используемые в memo, представляют собой значения id(), т. Е. Области памяти, поэтому они не распределяются случайным образом по пространству клавиш («средняя» часть выше) и могут вести себя хуже, вплоть до O (n^ 2) худший случай.Я действительно наблюдал некоторое снижение производительности при реальном использовании, но по большей части он вел себя как линейный.

Это часть сложности, но константа велика и deepcopy совсем не дешево и вполне может быть причиной ваших проблем.Единственный верный способ узнать это использовать профилировщик - сделать это.Кстати, я сейчас переписываю ужасно медленный код, который тратит 98% времени выполнения на deepcopy.

1 голос
/ 22 января 2012

Для чего вы используете deepcopy?Как следует из названия, deepcopy копирует объект и все подобъекты рекурсивно, поэтому потребуется время, пропорциональное размеру копируемого объекта.(с некоторыми дополнительными затратами для работы с циклическими ссылками)

Нет никакого способа ускорить его, если вы собираетесь копировать все, вам нужно копировать все.Один вопрос, который нужно задать: вам нужно скопировать все или просто скопировать часть структуры.

0 голосов
/ 22 января 2012

Сложность deepcopy() зависит от размера (количества элементов / дочерних элементов) копируемого объекта.

Если входные данные вашего алгоритма не влияют на размер копируемого объекта (объектов), то для определения сложности следует рассматривать вызов deeopcopy() как O(1), так как выполнение каждого вызовавремя относительно статично.

(Если входные данные вашего алгоритма влияют на размер копируемого объекта (объектов), вам нужно будет уточнить, как. Затем можно оценить сложность алгоритма.)

...