>-> if i in sieve:
>(Pdb) n
>> /home/rnd/workup/intuit–python/examples/Sieve.py(18)primes()
>-> sieve -= sets.Set(range(2*i, N, i))
>(Pdb) n
>> /home/rnd/workup/intuit–python/examples/Sieve.py(16)primes()
>-> for i in range(2, int(math.sqrt(N))):
>(Pdb) p sieve
>Set([2, 3, 5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37, 41, 43, 47, 49,
>53, 55, 59, 61, 65, 67, 71, 73, 77, 79, 83, 85, 89, 91, 95, 97])
Модуль profile
С помощью профайлера разработчики программного обеспечения могут узнать, сколько времени занимает исполнение различных функций и методов.
Продолжая пример с решетом Эратосфена, стоит посмотреть, как тратится процессорное время при вызове функции >primes()
:
>>>> profile.run("Sieve.primes(100000)")
> 709 function calls in 1.320 CPU seconds
>Ordered by: standard name
>ncalls tottime percall cumtime percall filename:lineno(function)
> 1 0.010 0.010 1.320 1.320 :1(?)
> 1 0.140 0.140 1.310 1.310 Sieve.py:13(primes)
> 1 0.000 0.000 1.320 1.320 profile:0(Sieve.primes(100000))
> 0 0.000 0.000 profile:0(profiler)
> 65 0.000 0.000 0.000 0.000 sets.py:119(__iter__)
> 314 0.000 0.000 0.000 0.000 sets.py:292(__contains__)
> 65 0.000 0.000 0.000 0.000 sets.py:339(_binary_sanity_check)
> 66 0.630 0.010 0.630 0.010 sets.py:356(_update)
> 66 0.000 0.000 0.630 0.010 sets.py:425(__init__)
> 65 0.010 0.000 0.540 0.008 sets.py:489(__isub__)
> 65 0.530 0.008 0.530 0.008 sets.py:495(difference_update)
Здесь >ncalls
— количество вызовов функции или метода, >tottime
— полное время выполнения кода функции (без времени нахождения в вызываемых функциях), >percall
— тоже, в пересчете на один вызов, >cumtime
— аккумулированное время нахождения в функции, вместе со всеми вызываемыми функциями. В последнем столбце приведено имя файла, номер строки с функцией или методов и его имя.
Примечание:
«Странные» имена, например, >__iter__
, >__contains__
и >__isub__
— имена методов, реализующих итерацию по элементам, проверку принадлежности элемента (>in
) и операцию >-=
. Метод >__init__
— конструктор объекта (в данном случае — множества).
Модуль unittest
При разработке программного обеспечения рекомендуется применять так называемые регрессионные испытания. Для каждого модуля составляется набор тестов, по возможности таким образом, чтобы проверялись не только типичные вычисления, но и «крайние», вырожденные случаи, чтобы испытания затронули каждую ветку алгоритма хотя бы один раз. Тест для данного модуля (написанный сразу после того, как определен интерфейс модуля) находится в файле