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