PythonのMatlabのticおよびtoc関数に相当するものは何ですか?
tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()
、それからprint toc-tic
。
PythonのMatlabのticおよびtoc関数に相当するものは何ですか?
tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()
、それからprint toc-tic
。
回答:
timeit
ThiefMasterが言及したこととは別に、それを行う簡単な方法は(インポートした後time
)です:
t = time.time()
# do stuff
elapsed = time.time() - t
使用したいヘルパークラスがあります。
class Timer(object):
def __init__(self, name=None):
self.name = name
def __enter__(self):
self.tstart = time.time()
def __exit__(self, type, value, traceback):
if self.name:
print('[%s]' % self.name,)
print('Elapsed: %s' % (time.time() - self.tstart))
コンテキストマネージャとして使用できます。
with Timer('foo_stuff'):
# do some foo
# do some stuff
時々、私はこのテクニックがより便利timeit
だと思います-それはすべてあなたが測定したいものに依存します。
time
コマンドを使用してプログラムのランタイムを永遠に測定してきましたが、この方法はこれをPythonコード内で複製します。仕事に適したツールである限り、問題はありません。timeit
常にそうであるとは限りません。プロファイラーは、ほとんどのニーズに対してはるかにヘビーウェイトのソリューションです
print 'Elapsed: %.2f seconds % (time.time() - self.tstart)'
ます。%.2fなしでは理解するのが難しいです。素晴らしいアイデアをありがとう。
elapsed = t - time.time()
代わりに欲しいと思いますelapsed = time.time() - t
。後者では経過はマイナスになります。この変更を編集として提案しました。
elapsed = time.time() - t
常にプラスの価値を生み出す形だと思います。
Matlabからpythonに移行したときも同じ質問がありました。このスレッドの助けを借りて、Matlab と関数の正確な類似物を構築することができました。スクリプトの上部に次のコードを挿入するだけです。tic()
toc()
import time
def TicTocGenerator():
# Generator that returns time differences
ti = 0 # initial time
tf = time.time() # final time
while True:
ti = tf
tf = time.time()
yield tf-ti # returns the time difference
TicToc = TicTocGenerator() # create an instance of the TicTocGen generator
# This will be the main function through which we define both tic() and toc()
def toc(tempBool=True):
# Prints the time difference yielded by generator instance TicToc
tempTimeInterval = next(TicToc)
if tempBool:
print( "Elapsed time: %f seconds.\n" %tempTimeInterval )
def tic():
# Records a time in TicToc, marks the beginning of a time interval
toc(False)
それでおしまい!これで、Matlab tic()
とtoc()
同様に、完全に使用する準備が整いました。例えば
tic()
time.sleep(5)
toc() # returns "Elapsed time: 5.00 seconds."
実際、これは組み込みのMatlab関数よりも用途が広いです。ここでは、の別のインスタンスを作成TicTocGenerator
して、複数の操作を追跡したり、別のタイミングで計測したりできます。たとえば、スクリプトのタイミングを計っているときに、スクリプト全体と同様に、スクリプトの各部分を別々に計時できるようになりました。(具体例を挙げます)
TicToc2 = TicTocGenerator() # create another instance of the TicTocGen generator
def toc2(tempBool=True):
# Prints the time difference yielded by generator instance TicToc2
tempTimeInterval = next(TicToc2)
if tempBool:
print( "Elapsed time 2: %f seconds.\n" %tempTimeInterval )
def tic2():
# Records a time in TicToc2, marks the beginning of a time interval
toc2(False)
これで、2つの別々の時間を計測できるはずです。次の例では、スクリプト全体とスクリプトの部分を別々に計測します。
tic()
time.sleep(5)
tic2()
time.sleep(3)
toc2() # returns "Elapsed time 2: 5.00 seconds."
toc() # returns "Elapsed time: 8.00 seconds."
実際には、tic()
毎回使用する必要はありません。あなたが時間を計りたい一連のコマンドを持っているなら、あなたは書くことができます
tic()
time.sleep(1)
toc() # returns "Elapsed time: 1.00 seconds."
time.sleep(2)
toc() # returns "Elapsed time: 2.00 seconds."
time.sleep(3)
toc() # returns "Elapsed time: 3.00 seconds."
# and so on...
これがお役に立てば幸いです。
ticとtocの絶対的な最高の類似物は、単純にそれらをpythonで定義することです。
def tic():
#Homemade version of matlab tic and toc functions
import time
global startTime_for_tictoc
startTime_for_tictoc = time.time()
def toc():
import time
if 'startTime_for_tictoc' in globals():
print "Elapsed time is " + str(time.time() - startTime_for_tictoc) + " seconds."
else:
print "Toc: start time not set"
その後、次のように使用できます。
tic()
# do stuff
toc()
tic
and のネストされた使用の場合、正しく動作しませんtoc
。もう少し高度なものが必要になります。
import time
かなり時間がかかる可能性があるため、両方の機能の外側を削除します。
tic
して、そこにプッシュしてtoc
ポップします。
timeit.default_timer()
よりも優れているtime.time()
ので、time.clock()
多くのOSに応じて、適切であるかもしれない
通常、IPythonの%time
、%timeit
、%prun
および%lprun
(1がいる場合line_profiler
インストールは)非常によく私のプロファイリングのニーズを満たします。ただし、tic-toc
対話型で、つまりユーザーがGUIでマウスを動かして計算をプロファイリングしようとしたときに、のような機能のユースケースが発生しました。インタラクティブにテストしている間、ソース内tic
のsをスパミングtoc
することが、ボトルネックを明らかにする最も早い方法だと感じました。私はEli BenderskyのTimer
クラスに行きましたが、コードのインデントを変更する必要があり、一部のエディターでは不便で、バージョン管理システムを混乱させるため、完全には満足していませんでした。さらに、異なる関数のポイント間の時間を測定する必要がある場合があります。これは、with
ステートメント。多くのPythonの巧妙さを試した後、私が最も効果的に機能することがわかったシンプルなソリューションを次に示します。
from time import time
_tstart_stack = []
def tic():
_tstart_stack.append(time())
def toc(fmt="Elapsed: %s s"):
print fmt % (time() - _tstart_stack.pop())
これはスタックの開始時間をプッシュすることで機能するため、tic
sとtoc
sの複数のレベルで正しく機能します。また、toc
ステートメントのフォーマット文字列を変更して、EliのTimer
クラスについて気に入った追加情報を表示することもできます。
どういうわけか、私は純粋なPython実装のオーバーヘッドに関心を持ったので、C拡張モジュールもテストしました。
#include <Python.h>
#include <mach/mach_time.h>
#define MAXDEPTH 100
uint64_t start[MAXDEPTH];
int lvl=0;
static PyObject* tic(PyObject *self, PyObject *args) {
start[lvl++] = mach_absolute_time();
Py_RETURN_NONE;
}
static PyObject* toc(PyObject *self, PyObject *args) {
return PyFloat_FromDouble(
(double)(mach_absolute_time() - start[--lvl]) / 1000000000L);
}
static PyObject* res(PyObject *self, PyObject *args) {
return tic(NULL, NULL), toc(NULL, NULL);
}
static PyMethodDef methods[] = {
{"tic", tic, METH_NOARGS, "Start timer"},
{"toc", toc, METH_NOARGS, "Stop timer"},
{"res", res, METH_NOARGS, "Test timer resolution"},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC
inittictoc(void) {
Py_InitModule("tictoc", methods);
}
これはMacOSX用でありlvl
、簡潔にするために範囲外かどうかを確認するコードは省略しています。一方でtictoc.res()
私のシステム上の利回りは約50ナノ秒の解像度を、私は任意のPythonの文を測定するジッタが(とはるかにIPythonから使用する場合)マイクロ秒の範囲で、容易であることがわかりました。この時点で、Python実装のオーバーヘッドは無視できる程度になるため、C実装と同じ信頼度で使用できます。
tic-toc
-approachの実用性は、実行に10マイクロ秒以上かかるコードブロックに実質的に限定されていることがわかりました。その下でtimeit
は、忠実な測定値を得るために、inのような平均化戦略が必要です。
ネストされたtic tocsを実現するためのモジュール[tictoc.py]を作成しました。これはMatlabが行うことです。
from time import time
tics = []
def tic():
tics.append(time())
def toc():
if len(tics)==0:
return None
else:
return time()-tics.pop()
そしてそれはこのように機能します:
from tictoc import tic, toc
# This keeps track of the whole process
tic()
# Timing a small portion of code (maybe a loop)
tic()
# -- Nested code here --
# End
toc() # This returns the elapse time (in seconds) since the last invocation of tic()
toc() # This does the same for the first tic()
お役に立てば幸いです。
timeit
モジュールを見てください。実際には同等ではありませんが、時間を計るコードが関数内にある場合は、簡単に使用できます。
pip install easy-tictoc
コードで:
from tictoc import tic, toc
tic()
#Some code
toc()
免責事項:私はこのライブラリの作者です。
これはラッパーを使用して行うこともできます。時間を保つための非常に一般的な方法。
このコード例のラッパーは関数をラップし、関数の実行に必要な時間を出力します。
def timethis(f):
import time
def wrapped(*args, **kwargs):
start = time.time()
r = f(*args, **kwargs)
print "Executing {0} took {1} seconds".format(f.func_name, time.time()-start)
return r
return wrapped
@timethis
def thistakestime():
for x in range(10000000):
pass
thistakestime()
@Eli Benderskyの回答を少し変更して、俳優を使用しました __init__()
し、デストラクタを__del__()
、それが元のコードをインデントすることなく、より便利に使用できるように、タイミングを行うには:
class Timer(object):
def __init__(self, name=None):
self.name = name
self.tstart = time.time()
def __del__(self):
if self.name:
print '%s elapsed: %.2fs' % (self.name, time.time() - self.tstart)
else:
print 'Elapsed: %.2fs' % (time.time() - self.tstart)
使用するには、単純にTimer( "blahblah")をローカルスコープの先頭に置きます。経過時間はスコープの最後に出力されます:
for i in xrange(5):
timer = Timer("eigh()")
x = numpy.random.random((4000,4000));
x = (x+x.T)/2
numpy.linalg.eigh(x)
print i+1
timer = None
それは印刷します:
1
eigh() elapsed: 10.13s
2
eigh() elapsed: 9.74s
3
eigh() elapsed: 10.70s
4
eigh() elapsed: 10.25s
5
eigh() elapsed: 11.28s
timer
、for
ループの後に他のコードが続く場合、最後の呼び出しの後に削除されないという事実です。最後のタイマー値を取得するtimer
には、for
ループを介して、たとえばを削除または上書きする必要がありますtimer = None
。
Python 3 に対するEliの回答の更新:
class Timer(object):
def __init__(self, name=None, filename=None):
self.name = name
self.filename = filename
def __enter__(self):
self.tstart = time.time()
def __exit__(self, type, value, traceback):
message = 'Elapsed: %.2f seconds' % (time.time() - self.tstart)
if self.name:
message = '[%s] ' % self.name + message
print(message)
if self.filename:
with open(self.filename,'a') as file:
print(str(datetime.datetime.now())+": ",message,file=file)
Eliと同じように、コンテキストマネージャーとして使用できます。
import time
with Timer('Count'):
for i in range(0,10_000_000):
pass
出力:
[Count] Elapsed: 0.27 seconds
また、報告された時間の単位(秒)を出力し、Canの提案に従って桁数をトリミングするように更新しました。また、ログファイルに追加することもできます。ロギング機能を使用するには、datetimeをインポートする必要があります。
import time
import datetime
with Timer('Count', 'log.txt'):
for i in range(0,10_000_000):
pass
ステファンとアントニモの答えに基づいて、私は結局
def Tictoc():
start_stack = []
start_named = {}
def tic(name=None):
if name is None:
start_stack.append(time())
else:
start_named[name] = time()
def toc(name=None):
if name is None:
start = start_stack.pop()
else:
start = start_named.pop(name)
elapsed = time() - start
return elapsed
return tic, toc
でutils.py
、モジュール、およびIはAでそれを使用します
from utils import Tictoc
tic, toc = Tictoc()
こちらです
tic()
、toc()
Matlabのようにそれらをネストすることができますtic(1)
、toc(1)
またはtic('very-important-block')
、toc('very-important-block')
および異なる名前のタイマーは干渉しません(ここでtocは経過時間を出力しませんが、それを返します。)
tic = time.time()
とtoc = time.time()
、その後、print toc-tic, 'sec Elapsed'
人々は以下の言ったように、しかし、timeit
より堅牢です。