Почему методы такие медленные? - PullRequest
1 голос
/ 28 февраля 2012

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

Но в Python, если у меня есть:

list_of_sets = generate_a_list_containg_a_bunch_of_sets()
intersection_of_all = reduce(list_of_sets[0].intersection, list_of_sets)

Это резко (в моих экспериментах около 40%) медленнее, чем:

list_of_sets = generate_a_list_containg_a_bunch_of_sets()
intersection_of_all = reduce(set.intersection, list_of_sets)

ЧтоЯ не понимаю, почему это должно быть намного медленнее, поиск метода (я бы подумал) происходил при вызове Reduce, поэтому не нужно искать внутреннюю часть структуры Reduce, где фактически вызывается метод пересечения.снова (просто повторное использование той же ссылки на метод).

Может ли кто-нибудь осветить, где мое понимание неверно?

1 Ответ

12 голосов
/ 28 февраля 2012

Это совершенно не связано с привязкой метода и т. Д. Первая версия вычисляет пересечение трех наборов в каждой итерации, в то время как вторая версия пересекает только два набора.Это легко увидеть, если вместо этого использовать явные циклы.

Вариант 1:

intersection = list_of_sets[0]
for s in list_of_sets[1:]:
    intersection = list_of_sets[0].intersection(intersection, s)

Вариант 2:

intersection = list_of_sets[0]
for s in list_of_sets[1:]:
    intersection = set.intersection(intersection, s)

(Согласитесь, сейчас у Гвидо естьточка?)

Обратите внимание, что это, вероятно, будет еще быстрее:

intersection = list_of_sets[0]
for s in list_of_sets[1:]:
    intersection.intersection_update(s)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...