Хотелось бы рассказать о модуле profile, который появился в PyS60 2.0(на самом деле в версию 2.0 включено очень много интересных и полезных модулей стандартной библиотеки Python, о которых многие не знают.Эти модули появились благодаря тому, что Python for S60 2.0 собран на базе компьютерного 2.5.4, и все нововведения "старшего" брата тоже в него вошли).
Итак, модуль profile - это профайлер , который можно использовать для сбора статистики о времени работы отдельных функций.Например когда требуется повысить быстродействие отдельного участка кода, можно протестировать профайлером варианты его(участка) реализаций, и выбрать менее ресурсоемкий.Для этого мы будем использовать функцию run() этого модуля.
Например, нам требуется посчитать суму чисел от 0 до 100, и на выбор у нас есть два варианта: использовать рекурсию(ну не знаю зачем, просто для примера) или цикл while:
import profile # импортируем модуль profile
def plus(cell, i): # объявляем рекурсивную функцию(cell - переменная для сохранения результата суммирования до следующего вызова,
cell+=i # i - счетчик и одновременно число для сложения с предыдущим результатом)
i+=1
if i>100: # если сложили все 100 чисел(0....100), выводим результат на экран
print cell
return
return plus(cell, i) # собственно, рекурсия(вызываем функцию из самой же себя)
profile.run("plus(0, 0)") # просим профайлер собрать и вывести вывести статистику выполнения нашей функции, и время выполнения(аргумент
# функции run() должен быть строкой с выражением или кодом
code="""cell_=0 # в переменную code сохраняем код выполнения нашей операции, но уже с циклом while(вместо рекурсии)
i=0
while i<=100:
cell_+=i
i+=1
print cell_"""
profile.run(code) # вызываем run(code) для профилирования
Запускаем наш скрипт и получаем следующее:
>>>
5050 # собственно результат
301 function calls (201 primitive calls) in 0.029 CPU seconds # рекурсия - вызов 301-й функции, 0.029 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
12 0.003 0.000 0.003 0.000 :0(acquire)
6 0.000 0.000 0.000 0.000 :0(allocate_lock)
3 0.000 0.000 0.000 0.000 :0(append)
3 0.000 0.000 0.000 0.000 :0(dumps)
3 0.000 0.000 0.000 0.000 :0(fileno)
3 0.000 0.000 0.000 0.000 :0(get)
15 0.000 0.000 0.000 0.000 :0(get_ident)
7 0.000 0.000 0.000 0.000 :0(has_key)
6 0.000 0.000 0.000 0.000 :0(isinstance)
9 0.000 0.000 0.000 0.000 :0(len)
3 0.000 0.000 0.000 0.000 :0(pack)
6 0.000 0.000 0.000 0.000 :0(release)
3 0.000 0.000 0.000 0.000 :0(select)
3 0.001 0.000 0.001 0.000 :0(send)
1 0.023 0.023 0.023 0.023 :0(setprofile)
1 0.000 0.000 0.006 0.006 :1()
3 0.000 0.000 0.000 0.000 :1(fileno)
1 0.000 0.000 0.029 0.029 profile:0(plus(0, 0))
0 0.000 0.000 profile:0(profiler)
101/1 0.000 0.000 0.006 0.006 recursion.py:2(plus)
21 0.000 0.000 0.000 0.000 rpc.py:149(debug)
3 0.000 0.000 0.005 0.002 rpc.py:208(remotecall)
3 0.000 0.000 0.001 0.000 rpc.py:218(asynccall)
3 0.000 0.000 0.004 0.001 rpc.py:238(asyncreturn)
3 0.000 0.000 0.000 0.000 rpc.py:244(decoderesponse)
3 0.000 0.000 0.004 0.001 rpc.py:279(getresponse)
3 0.000 0.000 0.000 0.000 rpc.py:287(_proxify)
3 0.000 0.000 0.004 0.001 rpc.py:295(_getresponse)
3 0.000 0.000 0.000 0.000 rpc.py:317(newseq)
3 0.000 0.000 0.001 0.000 rpc.py:321(putmessage)
3 0.000 0.000 0.001 0.000 rpc.py:548(__getattr__)
2 0.000 0.000 0.000 0.000 rpc.py:591(__init__)
2 0.000 0.000 0.004 0.002 rpc.py:596(__call__)
3 0.000 0.000 0.000 0.000 threading.py:101(__init__)
3 0.000 0.000 0.000 0.000 threading.py:116(acquire)
3 0.000 0.000 0.000 0.000 threading.py:136(release)
3 0.000 0.000 0.000 0.000 threading.py:154(_acquire_restore)
3 0.000 0.000 0.000 0.000 threading.py:162(_release_save)
3 0.000 0.000 0.000 0.000 threading.py:172(_is_owned)
3 0.000 0.000 0.000 0.000 threading.py:176(Condition)
3 0.000 0.000 0.000 0.000 threading.py:181(__init__)
3 0.000 0.000 0.003 0.001 threading.py:230(wait)
6 0.000 0.000 0.000 0.000 threading.py:59(__init__)
15 0.000 0.000 0.000 0.000 threading.py:64(_note)
6 0.000 0.000 0.000 0.000 threading.py:808(currentThread)
3 0.000 0.000 0.000 0.000 threading.py:96(RLock)
5050 #результат
135 function calls in 0.004 CPU seconds # цикл while - 135 вызовов, 0.004 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
8 0.003 0.000 0.003 0.000 :0(acquire)
4 0.000 0.000 0.000 0.000 :0(allocate_lock)
2 0.000 0.000 0.000 0.000 :0(append)
2 0.000 0.000 0.000 0.000 :0(dumps)
2 0.000 0.000 0.000 0.000 :0(fileno)
2 0.000 0.000 0.000 0.000 :0(get)
10 0.000 0.000 0.000 0.000 :0(get_ident)
4 0.000 0.000 0.000 0.000 :0(has_key)
4 0.000 0.000 0.000 0.000 :0(isinstance)
6 0.000 0.000 0.000 0.000 :0(len)
2 0.000 0.000 0.000 0.000 :0(pack)
4 0.000 0.000 0.000 0.000 :0(release)
2 0.000 0.000 0.000 0.000 :0(select)
2 0.000 0.000 0.000 0.000 :0(send)
1 0.000 0.000 0.000 0.000 :0(setprofile)
1 0.000 0.000 0.004 0.004 :1()
2 0.000 0.000 0.000 0.000 :1(fileno)
1 0.000 0.000 0.004 0.004 profile:0(cell_=0
i=0
while i<=100:
cell_+=i
i+=1
print cell_)
0 0.000 0.000 profile:0(profiler)
14 0.000 0.000 0.000 0.000 rpc.py:149(debug)
2 0.000 0.000 0.004 0.002 rpc.py:208(remotecall)
2 0.000 0.000 0.000 0.000 rpc.py:218(asynccall)
2 0.000 0.000 0.003 0.002 rpc.py:238(asyncreturn)
2 0.000 0.000 0.000 0.000 rpc.py:244(decoderesponse)
2 0.000 0.000 0.003 0.002 rpc.py:279(getresponse)
2 0.000 0.000 0.000 0.000 rpc.py:287(_proxify)
2 0.000 0.000 0.003 0.002 rpc.py:295(_getresponse)
2 0.000 0.000 0.000 0.000 rpc.py:317(newseq)
2 0.000 0.000 0.000 0.000 rpc.py:321(putmessage)
2 0.000 0.000 0.000 0.000 rpc.py:548(__getattr__)
2 0.000 0.000 0.000 0.000 rpc.py:591(__init__)
2 0.000 0.000 0.004 0.002 rpc.py:596(__call__)
2 0.000 0.000 0.000 0.000 threading.py:101(__init__)
2 0.000 0.000 0.000 0.000 threading.py:116(acquire)
2 0.000 0.000 0.000 0.000 threading.py:136(release)
2 0.000 0.000 0.000 0.000 threading.py:154(_acquire_restore)
2 0.000 0.000 0.000 0.000 threading.py:162(_release_save)
2 0.000 0.000 0.000 0.000 threading.py:172(_is_owned)
2 0.000 0.000 0.000 0.000 threading.py:176(Condition)
2 0.000 0.000 0.000 0.000 threading.py:181(__init__)
2 0.000 0.000 0.003 0.002 threading.py:230(wait)
4 0.000 0.000 0.000 0.000 threading.py:59(__init__)
10 0.000 0.000 0.000 0.000 threading.py:64(_note)
4 0.000 0.000 0.000 0.000 threading.py:808(currentThread)
2 0.000 0.000 0.000 0.000 threading.py:96(RLock)
ncalls - количество вызовов функции или метода;
tottime - полное время выполнения кода функции (без времени нахождения в вызываемых функциях);
percall - тоже, в пересчете на один вызов;
cumtime - аккумулированное время нахождения в функции, вместе со всеми вызываемыми функциями;
Последняя колонка - имя файла, номер строки с функцией или методов и его имя.
То есть 0, 029/0, 004=7, 25 - во столько раз быстрее выполнение нашей задачи при использовании цикла while(разумеется, это было очевидно с самого начала, но это же всего лишь пример).Таким образом, вы получаете простой и мощный инструмент для оптимизации кода, и нахождения "узких"
мест для последующего их рефакторинга с целью повышения еффективности.
Источник новости: dimonvideo.ru