简体   繁体   English

如何从脚本运行IPython魔术(或定时Python脚本)

[英]How to run an IPython magic from a script (or timing a Python script)

The IPython %timeit magic command does its job well for measuring time required to run some Python code. IPython%timeit magic命令可以很好地测量运行某些Python代码所需的时间。 Now, I want to use something analogous in the Python script. 现在,我想在Python脚本中使用类似的东西。 I know about the timeit module, however, it has several disadvantages, for example, how to select the number of runs adaptively? 我知道timeit模块,但它有几个缺点,例如,如何自适应地选择运行次数? ie, the default code 即默认代码

import timeit
t=timeit.Timer("code(f)", "from __main__ import code,f")
t.timeit() 

runs the code million times. 运行代码数百万次。 The %timeit IPyhton magic command does it automatically. %timeit IPyhton magic命令会自动执行此操作。 I suggest that I could use something like the MATLAB code http://www.mathworks.com/matlabcentral/fileexchange/18798 我建议我可以使用MATLAB代码http://www.mathworks.com/matlabcentral/fileexchange/18798

that does all the job automatically (and also tells if the overhead of the function is large). 自动完成所有工作(并且还告诉函数的开销是否很大)。

How can I call %timeit magic from a Python script (or maybe there is a better timing solution) ? 如何从Python脚本中调用%timeit magic(或者可能有更好的时序解决方案)?

It depends a bit on which version of IPython you have. 这取决于你拥有哪个版本的IPython。 If you have 1.x: 如果你有1.x:

from IPython import get_ipython
ipython = get_ipython()

If you have an older version: 如果您有旧版本:

import IPython.core.ipapi  
ipython = IPython.core.ipapi.get()

or 要么

import IPython.ipapi  
ipython = IPython.ipapi.get()

Once that's done , run a magic command like this: 完成后 ,运行如下魔术命令:

ipython.magic("timeit abs(-42)")

Note that the script must be run via ipython . 请注意,该脚本必须通过ipython运行。

Both IPython and the timeit module, when called with python -m timeit , execute the same loop with a growing value of number until the timing result surpasses a certain threshold that guarantees the time measurement is mostly free of operating system interferences. 当使用python -m timeit调用时,IPython和timeit模块都会执行相同的循环,其数字值会增加,直到定时结果超过某个阈值,从而确保时间测量基本上没有操作系统干扰。

You can compare the IPython implementation of the %timeit magic with the Python timeit standard module to see that they are doing mostly the same. 您可以将%timeit magicIPython实现Python timeit标准模块进行比较,看看它们的作用大致相同。

So, answering your question, you should probably replicate the same loop until you find the correct value for the number parameter. 所以,回答你的问题,你应该复制相同的循环,直到找到number参数的正确值。

The following works if one runs the Python script interactively in IPython. 如果在IPython中以交互方式运行Python脚本,则以下工作。 Eg, test.py : 例如, 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()')

Then run it interactively in IPython 然后在IPython中以交互方式运行它

%run -i test.py

to spit out the timings. 吐出时间。 The -i switch is necessary so that the variables are in scope. -i开关是必需的,以便变量在范围内。 I have not figured out how to do this without running an IPython instance, ie, by simply importing timeit from IPython and using it as a function. 我没有想到如何在不运行IPython实例的情况下执行此操作,即只需从IPython导入timeit并将其用作函数。 However, this solution works for my purposes, which is to automate some timing runs. 但是,此解决方案适用于我的目的,即自动执行某些计时运行。

According to the documentation of the timeit.py module, when timeit is run in command-line mode, 根据timeit.py模块的文档 ,当timeit在命令行模式下运行时,

If -n is not given, a suitable number of loops is calculated by trying successive powers of 10 until the total time is at least 0.2 seconds. 如果没有给出-n,则通过尝试10的连续幂来计算合适数量的环,直到总时间至少为0.2秒。

This is what IPython does. 这就是IPython所做的。 That is why the number of loops is always a power of 10. You could do something similar in your own code by embedding the call to t.timeit() inside a loop that makes sure you don't wait too long: 这就是为什么循环的数量始终是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)

This would ensure that the profiling time is at least 0.2 seconds, but not significantly more --- unless calling the function once takes a long time. 这将确保分析时间至少为0.2秒,但不会显着更多---除非一次调用该函数需要很长时间。

One way to run ipython magic function probably is using embed ipython instance. 运行ipython magic函数的一种方法可能是使用embed ipython实例。
For example: (most of the codes are borrowed from ipython website ) 例如:(大多数代码都是从ipython网站借来的)

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...')

This can work by using python interpreter 这可以通过使用python解释器来工作
PS: using dummy_mode will prevent from invoking interactive shell. PS:使用dummy_mode将阻止调用交互式shell。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM