212

正常に動作するPythonスクリプトがありますが、実行時間を記述する必要があります。私は使用すべきだとグーグルで検索しましたtimeitが、それを機能させることができないようです。

私のPythonスクリプトは次のようになります。

import sys
import getopt
import timeit
import random
import os
import re
import ibm_db
import time
from string import maketrans
myfile = open("results_update.txt", "a")

for r in range(100):
    rannumber = random.randint(0, 100)

    update = "update TABLE set val = %i where MyCount >= '2010' and MyCount < '2012' and number = '250'" % rannumber
    #print rannumber

    conn = ibm_db.pconnect("dsn=myDB","usrname","secretPWD")

for r in range(5):
    print "Run %s\n" % r        
    ibm_db.execute(query_stmt)
 query_stmt = ibm_db.prepare(conn, update)

myfile.close()
ibm_db.close(conn)

What I need is the time it takes to execute the query and write it to the file results_update.txt. The purpose is to test an update statement for my database with different indexes and tuning mechanisms.

4

9 に答える 9

349

タイミングを合わせたいブロックの前後や前後にtime.time()使用できます。time.clock()

import time

t0 = time.time()
code_block
t1 = time.time()

total = t1-t0

この方法は (数回の実行を平均化するわけではありません) ほど正確timeitではありませんが、簡単です。

time.time()(Windows および Linux の場合) およびtime.clock()(Linux の場合) は、高速な関数には十分な精度ではありません (合計 = 0 になります)。この場合、または複数回の実行で経過した時間を平均化したい場合は、関数を手動で複数回呼び出す必要があります (コード例で既に行っていると思いますが、number引数を設定すると timeit が自動的に行われます)

import time

def myfast():
   code

n = 10000
t0 = time.time()
for i in range(n): myfast()
t1 = time.time()

total_n = t1-t0

Windows では、Corey がコメントで述べたように、time.clock()精度がはるかに高く (秒ではなくマイクロ秒) time.time()、.

于 2010-05-19T14:32:35.007 に答える
54

コードのプロファイリングを行っていて、IPython を使用できる場合は、魔法の関数が含まれています%timeit

%%timeit細胞に作用します。

In [2]: %timeit cos(3.14)
10000000 loops, best of 3: 160 ns per loop

In [3]: %%timeit
   ...: cos(3.14)
   ...: x = 2 + 3
   ...: 
10000000 loops, best of 3: 196 ns per loop
于 2014-03-02T23:26:59.503 に答える
39

タイミングとはかなり別に、あなたが示すこのコードは単に間違っています.100回の接続を実行し(最後の接続を除くすべてを完全に無視します)、最初の実行呼び出しを行うときに、実行query_stmtにのみ初期化するローカル変数を渡します電話。

最初に、まだタイミングを気にせずにコードを正しくします。つまり、接続を確立または受信し、その接続で 100 または 500 または任意の数の更新を実行してから、接続を閉じる関数です。コードが正しく動作するようになったら、それを使用することを考えるのが正しいポイントtimeitです。

具体的には、時間を計測したい関数が呼び出されるパラメーターのない関数である場合、timeit.timeitfoobarを使用できます(2.6 以降 -- 2.5 以前ではより複雑です):

timeit.timeit('foobar()', number=1000)

3.5 以降、パラメーターを使用すると、パラメーターを受け取る関数でglobals簡単に使用できます。timeit

timeit.timeit('foobar(x,y)', number=1000, globals = globals())

実行回数を指定することをお勧めします。これは、デフォルトの 100 万回がユースケースでは高くなる可能性があるためです (このコードで多くの時間を費やすことになります;-)。

于 2010-05-19T14:33:06.043 に答える
14

1 つの特定のことに集中します。ディスク I/O は遅いので、微調整するのがデータベース クエリだけの場合は、テストから除外します。

また、データベースの実行時間を計る必要がある場合は、代わりに、クエリ プランを要求するなどのデータベース ツールを探してください。パフォーマンスは、正確なクエリと使用しているインデックスだけでなく、データ ロード (データの量) によっても異なることに注意してください。保存しました)。

timeit.timeit()つまり、コードを関数に入れ、その関数を次のように実行するだけです。

def function_to_repeat():
    # ...

duration = timeit.timeit(function_to_repeat, number=1000)

これにより、ガベージ コレクションが無効になり、関数が繰り返し呼び出され、特定のプラットフォームで利用可能な最も正確なクロックである をfunction_to_repeat()使用して、これらの呼び出しの合計時間が計測されます。timeit.default_timer()

繰り返し機能からセットアップ コードを移動する必要があります。たとえば、最初にデータベースに接続してから、クエリのみの時間を計測する必要があります。引数を使用しsetupてこれらの依存関係をインポートまたは作成し、関数に渡します。

def function_to_repeat(var1, var2):
    # ...

duration = timeit.timeit(
    'function_to_repeat(var1, var2)',
    'from __main__ import function_to_repeat, var1, var2', 
    number=1000)

globals を取得しfunction_to_repeatvar1スクリプトvar2からそれらを繰り返し関数に渡します。

于 2016-03-26T16:00:46.667 に答える
5

スティーブンの答えの簡単なラッパーを次に示します。この関数は繰り返し実行/平均化を行いません。タイミングコードをどこでも繰り返す必要がなくなるだけです:)

'''function which prints the wall time it takes to execute the given command'''
def time_func(func, *args): #*args can take 0 or more 
  import time
  start_time = time.time()
  func(*args)
  end_time = time.time()
  print("it took this long to run: {}".format(end_time-start_time))
于 2019-05-22T13:33:56.480 に答える
2

質問は既に回答されているようですが、同じことに対して 2 セント追加したいと思います。

また、いくつかのアプローチの実行時間をテストする必要があるという同様のシナリオに直面したため、記述されたすべての関数で timeit を呼び出す小さなスクリプトを記述しました。

このスクリプトは、こちらの github gist としても入手できます。

それがあなたや他の人に役立つことを願っています。

from random import random
import types

def list_without_comprehension():
    l = []
    for i in xrange(1000):
        l.append(int(random()*100 % 100))
    return l

def list_with_comprehension():
    # 1K random numbers between 0 to 100
    l = [int(random()*100 % 100) for _ in xrange(1000)]
    return l


# operations on list_without_comprehension
def sort_list_without_comprehension():
    list_without_comprehension().sort()

def reverse_sort_list_without_comprehension():
    list_without_comprehension().sort(reverse=True)

def sorted_list_without_comprehension():
    sorted(list_without_comprehension())


# operations on list_with_comprehension
def sort_list_with_comprehension():
    list_with_comprehension().sort()

def reverse_sort_list_with_comprehension():
    list_with_comprehension().sort(reverse=True)

def sorted_list_with_comprehension():
    sorted(list_with_comprehension())


def main():
    objs = globals()
    funcs = []
    f = open("timeit_demo.sh", "w+")

    for objname in objs:
        if objname != 'main' and type(objs[objname]) == types.FunctionType:
            funcs.append(objname)
    funcs.sort()
    for func in funcs:
        f.write('''echo "Timing: %(funcname)s"
python -m timeit "import timeit_demo; timeit_demo.%(funcname)s();"\n\n
echo "------------------------------------------------------------"
''' % dict(
                funcname = func,
                )
            )

    f.close()

if __name__ == "__main__":
    main()

    from os import system

    #Works only for *nix platforms
    system("/bin/bash timeit_demo.sh")

    #un-comment below for windows
    #system("cmd timeit_demo.sh")
于 2015-12-19T11:07:44.970 に答える