Почему у меня разные результаты между списком профилирования и генератором? - PullRequest
1 голос
/ 26 апреля 2020

Я работаю над python функцией на графиках, которая является рекурсивной и NP комплексной. Тем не менее, у меня были результаты очень долго, поэтому я использовал kernprof, чтобы увидеть, какие строки занимают больше времени.

Я увидел, что эта строка отнимает больше времени, чем я думал:

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
...
    53    120244     740797.0      6.2     17.0             if any( [m[passed].get(i, False) for passed in isom] ): # si ce noeud est lié à un noeud passé, le tester

Так что я решил использовать генератор, потому что, похоже, мне не следует генерировать весь список, потому что мне просто интересно, если таковое есть.

Но с генератором у меня есть такой результат:

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
...
    53     35283     509901.0     14.5     12.8             if any( (m[passed].get(i, False) for passed in isom) ): # si ce noeud est lié à un noeud passé, le tester

Так что кажется, что это быстрее, чем с пониманием списка, но я не понимаю, почему время на удар больше, и почему у меня гораздо меньше хитов?

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

Похоже, вы не сравниваете апельсины с апельсинами.

Похоже, что попадания в список понимания подсчитывают количество элементов в списке. Поскольку вы фактически создаете список и только применяете any () к результирующему объекту, вы будете систематически перебирать все элементы isom (отсюда и большое количество попаданий).

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

Что касается времени на попадание, ваше общее время составляет только меньше на долю (из-за других накладных расходов), но ваш счетчик попаданий меньше на порядок, поэтому коэффициент времени на попадание, естественно, будет выше. Это соотношение фактически не измеряет разницу между итератором и пониманием списка, потому что совпадения не рассчитываются на одной и той же основе. Для того чтобы иметь содержательное сравнение, вы должны использовать общий делитель (в идеале, фактическое количество раз, которое выполняется строка). Если вы сравните время на одно попадание на основе исходного количества обращений (т. Е. Общего времени для того же объема работы 509901.0 / 120244), то итератор "на одно попадание" будет равен 4,2

.
0 голосов
/ 27 апреля 2020

Ответы часто задаваемых вопросов rkern (https://github.com/rkern/line_profiler) на этот вопрос:

Почему у моих списочных представлений столько хитов, когда я использую LineProfiler?

LineProfiler записывает строку с пониманием списка по одному разу для каждой итерации понимания списка.

И это объясняет, я думаю, почему время на попадание выше с генератором, как в списке много попаданий - это просто итерация, которая возвращает false, но с генератором много попаданий - для генерации генератора, которая медленнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...