programing

Pythons 타임릿을 사용하여 성능을 테스트하기 위한 코드 세그먼트를 어떻게 시간을 잴 수 있습니까?

randomtip 2022. 12. 31. 18:05
반응형

Pythons 타임릿을 사용하여 성능을 테스트하기 위한 코드 세그먼트를 어떻게 시간을 잴 수 있습니까?

Python 스크립트는 정상적으로 동작하지만 실행 시간을 기입해야 합니다.써야 한다고 검색했는데 작동이 안 되는 것 같아요.

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)

필요한 것은 쿼리를 실행하고 파일에 쓰는 데 걸리는 시간입니다.results_update.txt다른 인덱스와 튜닝 메커니즘으로 데이터베이스의 업데이트 문을 테스트하는 것이 목적입니다.

시간을 설정할 블록의 전후 또는 전후를 사용할 수 있습니다.

import time

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

total = t1-t0

이 방법은 (여러 런의 평균을 산출하지 않음)만큼 정확하지는 않지만 간단합니다.

time.time()(Windows 및 Linux의 경우) 및time.clock()(Linux의 경우)는 빠른 기능을 수행할 수 있을 만큼 정확하지 않습니다(총 = 0).이 경우 또는 여러 번의 실행으로 경과된 시간을 평균화하려면 함수를 수동으로 여러 번 호출해야 합니다(이미 예시와 같이 코드와 시간은 인수를 설정하면 자동으로 호출됩니다).

import time

def myfast():
   code

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

total_n = t1-t0

Windows 에서는, 코리가 코멘트에서 말한 것처럼,time.clock()훨씬 높은 정밀도(초단위가 아닌 마이크로초단위가)를 가지며, 보다 선호됩니다.time.time().

코드를 프로파일링하고 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

타이밍과는 전혀 별도로 표시되는 이 코드는 단순히 올바르지 않습니다.즉, 100개의 접속을 실행하고(마지막 1개를 제외한 모든 접속을 완전히 무시), 첫 번째 실행 콜을 실행할 때 로컬 변수를 전달합니다.query_stmt이것은 실행 콜 후에만 초기화됩니다.

우선, 타이밍을 신경 쓰지 않고 코드를 수정해 주세요.즉, 접속을 확립 또는 수신해, 100 또는 500, 또는 그 접속에 관한 갱신을 실행한 후, 접속을 종료하는 기능입니다.코드가 올바르게 동작하고 있는 경우는, 이 코드의 사용을 검토하는 것이 올바른 시점입니다.timeit하고 있어!

구체적으로 시간을 설정하는 함수가 파라미터가 없는 함수일 경우foobartimeit.timeit(2.6 이후 - 2.5 이전 버전에서는 더 복잡함)을 사용할 수 있습니다.

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

3.5 이후로는globals파라미터를 사용하면 쉽게 사용할 수 있습니다.timeit매개 변수를 사용하는 기능을 포함합니다.

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

사용 사례에 대해 기본값인 100만 개가 높을 수 있으므로 실행 수를 지정하는 것이 좋습니다(이 코드에서 많은 시간을 소비하게 됩니다;-).

가지 특정한 것에 집중하세요.디스크 I/O가 느리므로 데이터베이스 쿼리만 조정할 경우 테스트에서 제외합니다.

또한 데이터베이스 실행 시간을 재야 할 경우 쿼리 계획 요청과 같은 데이터베이스 도구를 찾습니다. 성능은 정확한 쿼리 및 보유하고 있는 인덱스뿐만 아니라 데이터 로드(저장된 데이터 양)에 따라 달라집니다.

즉, 단순히 코드를 함수에 넣고 다음 명령을 사용하여 해당 함수를 실행할 수 있습니다.

def function_to_repeat():
    # ...

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

수집이 으로 가비지 수집이 됩니다.반복적으로function_to_repeat()를 사용하여 이들 콜의 총 지속시간을 나타냅니다.이것은 특정 플랫폼에서 사용 가능한 가장 정확한 클럭입니다.

예를 들어 먼저 데이터베이스에 연결한 다음 쿼리 시간만 설정하는 등 설정 코드를 반복된 기능에서 이동해야 합니다.를 사용합니다.setup이러한 의존관계를 Import 또는 생성하여 함수에 전달하기 위한 인수입니다.

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

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

function_to_repeat,var1 ★★★★★★★★★★★★★★★★★」var2반복할 때마다 스크립트의 내용을 함수에 전달합니다.

여기 스티븐의 대답에 대한 간단한 포장지가 있습니다.이 기능은 반복 실행/평균을 수행하지 않으며, 모든 위치에서 타이밍 코드를 반복할 필요가 없습니다.

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

질문에 대한 답변은 이미 끝났지만, 같은 금액에 2센트를 더하고 싶습니다.

또, 몇개의 어프로치에 대해서 실행 시간을 테스트해, 거기에 써진 모든 함수의 타임릿을 호출하는 작은 스크립트를 작성하는 시나리오도 있습니다.

이 스크립트는 여기서 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")

를 사용하여 방법timeit:

import timeit

def time_this():
    return 'a' + 'b'

timeit.timeit(time_this, number=1000)

명령어는 실행하는데 을 초 합니다.time_this()1000파운드

에서는 Import한 「Import」를 사용하려고 timeit★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 이 이므로, 이 답변의 로서, 이 답변이 있습니다.timeit마르틴의 답변에 대해 자세히 설명하는 것 같습니다.

에 대한 문서는 확인할 가치가 있는 많은 예시와 플래그를 제공합니다.명령줄의 기본 사용법은 다음과 같습니다.

$ python -mtimeit "all(True for _ in range(1000))"
2000 loops, best of 5: 161 usec per loop
$ python -mtimeit "all([True for _ in range(1000)])"
2000 loops, best of 5: 116 usec per loop

「」와 함께 -h모든 옵션을 표시합니다.Python MOTW에는 다음 섹션이 있습니다.timeit에 명령줄에서 Import 코드스트링 및 멀티라인 코드스트링을 사용하여 모듈을 실행하는 방법을 나타냅니다.

스크립트 형식에서는 보통 다음과 같이 사용합니다.

import argparse
import copy
import dis
import inspect
import random
import sys
import timeit

def test_slice(L):
    L[:]

def test_copy(L):
    L.copy()

def test_deepcopy(L):
    copy.deepcopy(L)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--n", type=int, default=10 ** 5)
    parser.add_argument("--trials", type=int, default=100)
    parser.add_argument("--dis", action="store_true")
    args = parser.parse_args()
    n = args.n
    trials = args.trials
    namespace = dict(L = random.sample(range(n), k=n))
    funcs_to_test = [x for x in locals().values() 
                     if callable(x) and x.__module__ == __name__]
    print(f"{'-' * 30}\nn = {n}, {trials} trials\n{'-' * 30}\n")

    for func in funcs_to_test:
        fname = func.__name__
        fargs = ", ".join(inspect.signature(func).parameters)
        stmt = f"{fname}({fargs})"
        setup = f"from __main__ import {fname}"
        time = timeit.timeit(stmt, setup, number=trials, globals=namespace)
        print(inspect.getsource(globals().get(fname)))

        if args.dis:
            dis.dis(globals().get(fname))

        print(f"time (s) => {time}\n{'-' * 30}\n")

필요한 기능과 인수를 쉽게 입력할 수 있습니다.불순물 기능 사용 시 주의하여 상태를 관리하십시오.

샘플 출력:

$ python benchmark.py --n 10000
------------------------------
n = 10000, 100 trials
------------------------------

def test_slice(L):
    L[:]

time (s) => 0.015502399999999972
------------------------------

def test_copy(L):
    L.copy()

time (s) => 0.01651419999999998
------------------------------

def test_deepcopy(L):
    copy.deepcopy(L)

time (s) => 2.136012
------------------------------

또 다른 간단한 타임릿의 예는 다음과 같습니다.

def your_function_to_test():
   # do some stuff...

time_to_run_100_times = timeit.timeit(lambda: your_function_to_test, number=100)

언급URL : https://stackoverflow.com/questions/2866380/how-can-i-time-a-code-segment-for-testing-performance-with-pythons-timeit

반응형