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

时间:2021-11-15 01:18:07

The IPython %timeit magic command does its job well for measuring time required to run some Python code. Now, I want to use something analogous in the Python script. I know about the timeit module, however, it has several disadvantages, for example, how to select the number of runs adaptively? i.e., the default code

IPython%timeit magic命令可以很好地测量运行某些Python代码所需的时间。现在,我想在Python脚本中使用类似的东西。我知道timeit模块,但它有几个缺点,例如,如何自适应地选择运行次数?即默认代码

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. I suggest that I could use something like the MATLAB code http://www.mathworks.com/matlabcentral/fileexchange/18798

运行代码数百万次。 %timeit IPyhton magic命令会自动执行此操作。我建议我可以使用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(或者可能有更好的时序解决方案)?

5 个解决方案

#1


46  

It depends a bit on which version of IPython you have. If you have 1.x:

这取决于你拥有哪个版本的IPython。如果你有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运行。

#2


5  

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 magic的IPython实现与Python timeit标准模块进行比较,看看它们的作用大致相同。

So, answering your question, you should probably replicate the same loop until you find the correct value for the number parameter.

因此,回答您的问题,您应该复制相同的循环,直到找到number参数的正确值。

#3


2  

The following works if one runs the Python script interactively in IPython. E.g., test.py:

如果在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()')

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 have not figured out how to do this without running an IPython instance, i.e., by simply importing timeit from IPython and using it as a function. However, this solution works for my purposes, which is to automate some timing runs.

吐出时间。 -i开关是必需的,以便变量在范围内。我没有想到如何在不运行IPython实例的情况下执行此操作,即只需从IPython导入timeit并将其用作函数。但是,此解决方案适用于我的目的,即自动执行某些计时运行。

#4


1  

One way to run ipython magic function probably is using embed ipython instance.
For example: (most of the codes are borrowed from ipython website)

运行ipython magic函数的一种方法可能是使用embed ipython实例。例如:(大部分代码都是从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
PS: using dummy_mode will prevent from invoking interactive shell.

这可以通过使用python解释器PS来工作:使用dummy_mode将阻止调用交互式shell。

#5


1  

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. 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:

这就是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)

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秒,但不会显着更多---除非一次调用该函数需要很长时间。

#1


46  

It depends a bit on which version of IPython you have. If you have 1.x:

这取决于你拥有哪个版本的IPython。如果你有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运行。

#2


5  

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 magic的IPython实现与Python timeit标准模块进行比较,看看它们的作用大致相同。

So, answering your question, you should probably replicate the same loop until you find the correct value for the number parameter.

因此,回答您的问题,您应该复制相同的循环,直到找到number参数的正确值。

#3


2  

The following works if one runs the Python script interactively in IPython. E.g., test.py:

如果在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()')

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 have not figured out how to do this without running an IPython instance, i.e., by simply importing timeit from IPython and using it as a function. However, this solution works for my purposes, which is to automate some timing runs.

吐出时间。 -i开关是必需的,以便变量在范围内。我没有想到如何在不运行IPython实例的情况下执行此操作,即只需从IPython导入timeit并将其用作函数。但是,此解决方案适用于我的目的,即自动执行某些计时运行。

#4


1  

One way to run ipython magic function probably is using embed ipython instance.
For example: (most of the codes are borrowed from ipython website)

运行ipython magic函数的一种方法可能是使用embed ipython实例。例如:(大部分代码都是从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
PS: using dummy_mode will prevent from invoking interactive shell.

这可以通过使用python解释器PS来工作:使用dummy_mode将阻止调用交互式shell。

#5


1  

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. 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:

这就是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)

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秒,但不会显着更多---除非一次调用该函数需要很长时间。