Project Euler和其他编码竞赛通常有最长的运行时间,或者人们吹嘘他们的特定解决方案运行速度有多快。对于Python,有时方法有些笨拙——即向__main__添加计时代码。
描述Python程序运行时间的好方法是什么?
Project Euler和其他编码竞赛通常有最长的运行时间,或者人们吹嘘他们的特定解决方案运行速度有多快。对于Python,有时方法有些笨拙——即向__main__添加计时代码。
描述Python程序运行时间的好方法是什么?
当前回答
如果你想做一个累积分析器,意思是连续运行函数几次并观察结果的总和。
您可以使用此cumulative_profiler装饰器:
它是python>=3.6特定的,但您可以删除非本地的,因为它可以在旧版本上工作。
import cProfile, pstats
class _ProfileFunc:
def __init__(self, func, sort_stats_by):
self.func = func
self.profile_runs = []
self.sort_stats_by = sort_stats_by
def __call__(self, *args, **kwargs):
pr = cProfile.Profile()
pr.enable() # this is the profiling section
retval = self.func(*args, **kwargs)
pr.disable()
self.profile_runs.append(pr)
ps = pstats.Stats(*self.profile_runs).sort_stats(self.sort_stats_by)
return retval, ps
def cumulative_profiler(amount_of_times, sort_stats_by='time'):
def real_decorator(function):
def wrapper(*args, **kwargs):
nonlocal function, amount_of_times, sort_stats_by # for python 2.x remove this row
profiled_func = _ProfileFunc(function, sort_stats_by)
for i in range(amount_of_times):
retval, ps = profiled_func(*args, **kwargs)
ps.print_stats()
return retval # returns the results of the function
return wrapper
if callable(amount_of_times): # incase you don't want to specify the amount of times
func = amount_of_times # amount_of_times is the function in here
amount_of_times = 5 # the default amount
return real_decorator(func)
return real_decorator
实例
剖析函数baz
import time
@cumulative_profiler
def baz():
time.sleep(1)
time.sleep(2)
return 1
baz()
baz跑了5次并打印了以下内容:
20 function calls in 15.003 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
10 15.003 1.500 15.003 1.500 {built-in method time.sleep}
5 0.000 0.000 15.003 3.001 <ipython-input-9-c89afe010372>:3(baz)
5 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
指定次数
@cumulative_profiler(3)
def baz():
...
其他回答
如果你想做一个累积分析器,意思是连续运行函数几次并观察结果的总和。
您可以使用此cumulative_profiler装饰器:
它是python>=3.6特定的,但您可以删除非本地的,因为它可以在旧版本上工作。
import cProfile, pstats
class _ProfileFunc:
def __init__(self, func, sort_stats_by):
self.func = func
self.profile_runs = []
self.sort_stats_by = sort_stats_by
def __call__(self, *args, **kwargs):
pr = cProfile.Profile()
pr.enable() # this is the profiling section
retval = self.func(*args, **kwargs)
pr.disable()
self.profile_runs.append(pr)
ps = pstats.Stats(*self.profile_runs).sort_stats(self.sort_stats_by)
return retval, ps
def cumulative_profiler(amount_of_times, sort_stats_by='time'):
def real_decorator(function):
def wrapper(*args, **kwargs):
nonlocal function, amount_of_times, sort_stats_by # for python 2.x remove this row
profiled_func = _ProfileFunc(function, sort_stats_by)
for i in range(amount_of_times):
retval, ps = profiled_func(*args, **kwargs)
ps.print_stats()
return retval # returns the results of the function
return wrapper
if callable(amount_of_times): # incase you don't want to specify the amount of times
func = amount_of_times # amount_of_times is the function in here
amount_of_times = 5 # the default amount
return real_decorator(func)
return real_decorator
实例
剖析函数baz
import time
@cumulative_profiler
def baz():
time.sleep(1)
time.sleep(2)
return 1
baz()
baz跑了5次并打印了以下内容:
20 function calls in 15.003 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
10 15.003 1.500 15.003 1.500 {built-in method time.sleep}
5 0.000 0.000 15.003 3.001 <ipython-input-9-c89afe010372>:3(baz)
5 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
指定次数
@cumulative_profiler(3)
def baz():
...
gprof2dot_magic公司
gprof2dot的神奇函数,用于在JupyterLab或Jupyter Notebook中将任何Python语句作为DOT图进行评测。
GitHub回购:https://github.com/mattijn/gprof2dot_magic
安装
确保您有Python包gprof2dot_magic。
pip install gprof2dot_magic
它的依赖关系gprof2dot和graphviz也将被安装
用法
要启用magic函数,首先加载gprof2dot_magic模块
%load_ext gprof2dot_magic
然后将任何行语句配置为DOT图,如下所示:
%gprof2dot print('hello world')
添加到https://stackoverflow.com/a/582337/1070617,
我编写了这个模块,允许您使用cProfile并轻松查看其输出。更多信息:https://github.com/ymichael/cprofilev
$ python -m cprofilev /your/python/program
# Go to http://localhost:4000 to view collected statistics.
另请参见:http://ymichael.com/2014/03/08/profiling-python-with-cprofile.html如何理解收集的统计数据。
获取IPython笔记本上的快速配置文件统计信息。人们可以将line_profiler和memory_profile直接嵌入到笔记本中。
另一个有用的包是Pympler。它是一个强大的评测包,能够跟踪类、对象、函数、内存泄漏等。
了解了!
!pip install line_profiler
!pip install memory_profiler
!pip install pympler
加载它!
%load_ext line_profiler
%load_ext memory_profiler
使用它!
%时间
%time print('Outputs CPU time,Wall Clock time')
#CPU times: user 2 µs, sys: 0 ns, total: 2 µs Wall time: 5.96 µs
给予:
CPU时间:CPU级执行时间systimes:系统级执行时间总计:CPU时间+系统时间墙上时间:墙上时钟时间
%计时
%timeit -r 7 -n 1000 print('Outputs execution time of the snippet')
#1000 loops, best of 7: 7.46 ns per loop
给出给定循环次数(n)中的最佳运行次数(r)。输出系统缓存的详细信息:当代码片段被多次执行时,系统会缓存一些操作并不再执行,这可能会影响概要文件报告的准确性。
%普鲁士人
%prun -s cumulative 'Code to profile'
给予:
函数调用数(ncall)每个函数调用有个条目(不同)每次呼叫所用时间(百分比)到函数调用为止的时间(cumtime)调用的函数/模块的名称等。。。
%记忆,记忆
%memit 'Code to profile'
#peak memory: 199.45 MiB, increment: 0.00 MiB
给予:
内存使用情况
%低压运行
#Example function
def fun():
for i in range(10):
print(i)
#Usage: %lprun <name_of_the_function> function
%lprun -f fun fun()
给予:
按行统计
系统大小
sys.getsizeof('code to profile')
# 64 bytes
返回对象的大小(以字节为单位)。
来自pympler的asizeof()
from pympler import asizeof
obj = [1,2,("hey","ha"),3]
print(asizeof.asizeof(obj,stats=4))
pympler.asizeof可用于调查某些Python对象消耗多少内存。与sys.getsizeof不同,asizeof递归地调整对象大小
来自pympler的跟踪器
from pympler import tracker
tr = tracker.SummaryTracker()
def fun():
li = [1,2,3]
di = {"ha":"haha","duh":"Umm"}
fun()
tr.print_diff()
跟踪函数的生存期。
Pympler包包含大量用于评测代码的高实用函数。这里无法涵盖所有这些。有关详细的概要文件实现,请参阅随附的文档。
Pympler文档
当我不是服务器的根用户时,我使用lsprofcalltree.py并像这样运行我的程序:
python lsprofcalltree.py -o callgrind.1 test.py
然后我可以用任何callgrind兼容的软件打开报告,比如qcachegrind