IPython%timeit magic命令可以很好地测量运行某些Python代码所需的时间。现在,我想在Python脚本中使用类似的东西。我知道timeit模块,但它有几个缺点,例如,如何自适应地选择运行次数?即默认代码
import timeit
t=timeit.Timer("code(f)", "from __main__ import code,f")
t.timeit()
运行代码数百万次。 %timeit IPyhton magic命令会自动执行此操作。我建议我可以使用类似MATLAB代码的东西 http://www.mathworks.com/matlabcentral/fileexchange/18798
自动完成所有工作(并且还会告诉函数的开销是否很大)。
如何从Python脚本调用%timeit magic(或者可能有更好的时序解决方案)?
答案 0 :(得分:54)
这取决于你拥有哪个版本的IPython。如果您有1.x:
from IPython import get_ipython
ipython = get_ipython()
如果你有旧版本:
import IPython.core.ipapi
ipython = IPython.core.ipapi.get()
或
import IPython.ipapi
ipython = IPython.ipapi.get()
完成后,运行如下魔术命令:
ipython.magic("timeit abs(-42)")
请注意,该脚本必须通过ipython
运行。
答案 1 :(得分:6)
当使用timeit
调用时,IPython和python -m timeit
模块都执行相同的循环,其中 number 的值越来越大,直到时序结果超过某个保证的阈值时间测量基本上没有操作系统干扰。
您可以将IPython implementation of the %timeit
magic与Python timeit
standard module进行比较,看看他们的行为大致相同。
因此,在回答您的问题时,您应该复制相同的循环,直到找到 number 参数的正确值。
答案 2 :(得分:3)
如果在IPython中以交互方式运行Python脚本,则以下工作正常。例如,test.py
:
def f():
# Algorithm 1
pass
def g():
# Algorithm 2
pass
# which one is faster?
mgc = get_ipython().magic
mgc(u'%timeit f()')
mgc(u'%timeit g()')
然后在IPython中以交互方式运行
%run -i test.py
吐出时间。 -i
开关是必需的,以便变量在范围内。我没有想到如何在不运行IPython实例的情况下执行此操作,即只需从IPython导入timeit
并将其用作函数即可。但是,这个解决方案适用于我的目的,即自动执行一些计时运行。
答案 3 :(得分:2)
根据timeit.py
模块的documentation,当timeit
在命令行模式下运行时,
如果没有给出-n,则通过尝试10的连续幂来计算合适数量的循环,直到总时间至少为0.2秒。
这就是IPython所做的。这就是为什么循环的数量始终是10的幂。你可以在你自己的代码中做类似的事情,通过在循环中嵌入对t.timeit()
的调用来确保你不要等待太久:
import timeit
t = timeit.Timer("code(f)", "from __main__ import code, f")
max_time = 0.2
N = 0
curr_time = t.timeit(1)
while curr_time < max_time:
N += 1
curr_time = t.timeit(10**N)
mean_time = curr_time / float(10**N)
这将确保分析时间至少为0.2秒,但不会显着更多---除非一次调用该函数需要很长时间。
答案 4 :(得分:1)
运行ipython magic函数的一种方法可能是使用embed ipython实例 例如:(大多数代码都是从ipython website借来的)
from IPython.terminal.embed import InteractiveShellEmbed
ipshell = InteractiveShellEmbed()
ipshell.dummy_mode = True
print('\nTrying to call IPython which is now "dummy":')
ipshell.magic("%timeit abs(-42)");
ipshell()
print('Nothing happened...')
这可以通过使用python解释器来工作 PS:使用dummy_mode将阻止调用交互式shell。