Trying to add executing Process(Test,a,b) Name in the decoration where i am calculating Elapsed Time.Need Suggestions.
Final Expected Logs:
Process **a** elapsed time :3.8 || Rowcount=1833
Process **test** elapsed time :7.8 || Rowcount=1133
code
import time
from queries import a,b,test
def elapsedTimeTracker_decorator(func):
def wrapper():
start_time = time.time()
func()
print(test)
end_time = time.time()
elapsed_time = end_time - start_time
print('elapsed_time:'+ str(elapsed_time) +'||' + 'RowCount:' + str(cursor.rowcount))
return wrapper
print "Process a started"
elapsedTimeTracker_decorator(lambda: cursor.execute(a))()
print "Process Test started"
elapsedTimeTracker_decorator(lambda: cursor.execute(Test))()
print "Process b started"
elapsedTimeTracker_decorator(lambda: cursor.execute(b))()
a,b & test Consists of SQL Update Queries
test = """INSERT INTO users
select * from user_all where user_id=54549172 """
If you wish to print extra data for a decorated lambda that takes no arguments, then you have to pass it to your decorator:
def elapsedTimeTracker_decorator(func, test):
def wrapper():
start_time = time.time()
func()
print(f'Process {test} elapsed time: {time.time() - start_time} || Rowcount={cursor.rowcount}')
return wrapper
elapsedTimeTracker_decorator(lambda: cursor.execute(test), test)()
Other than that I have no idea where your test is supposed to comes from. Please elaborate with more details if that is not a suitable solution.
EDIT: Based on the latest information provided, it is clear that you do not need to use a lambda, nor a decorator with an inner wrapper. You could simply use a simple function that call the given one with the provided arguments and keywords that would take care of the call along with printing the execution time. For example:
from time import time as now
def time_call(func, *args, **kwargs):
cur = now()
func(*args, **kwargs)
print(
f'Executing {func.__qualname__}({repr(args)[1:-1]}, ' +
f'{"".join(f"{k}={v}" for k, v in kwargs.items())}) took ' +
f'{now() - cur} seconds.'
)
def test(foo, bar, baz):
pass
time_call(test, 'foo', 'bar', baz=None)
Which would prints something like:
Executing test('foo', 'bar', baz=None) took 0.0 seconds.
Related
I have a function wrapper for my test cases that keeps track of how much time the function takes, then outputs some basic info using print. The code for my function wrapper is below:
TEST_INIT_START = datetime.datetime.now()
def timedisplay(func):
#functools.wraps(func)
def wrapper(self, *args, **kwargs):
start = datetime.datetime.now()
try:
return func(self, *args, **kwargs)
finally:
print()
print(
'Total time elapsed:',
(datetime.datetime.now() - TEST_INIT_START).seconds,
'seconds',
)
print(
f'{func.__name__} test time elapsed:',
(datetime.datetime.now() - start).seconds,
'seconds',
)
print('Result: ', end='')
return wrapper
The expected output for a test case using this wrapper would be something like:
test_some_function (tests.test_some_function) ...
Total time elapsed: 2 seconds
test_some_function test time elapsed: 2 seconds
Result: ok
But the weird thing is this is what I'm actually getting:
test_some_function (tests.test_some_function) ... Result:
Total time elapsed: 2 seconds
test_some_function test time elapsed: 2 seconds
ok
For some reason the output is getting written to the console with the final print statement first. My first thought would be that the calls to datetime.datetime.now() are releasing the GIL and executing the most simple statement before it's required, but I don't have any information to back that up. My question is mainly why this would be happening, and how to get it to execute properly.
I have the following celery chain process:
#app.task(name='bcakground')
def background_task():
now = datetime.now()
ids = [700,701,708,722,783,799]
for id in ids:
my_process = chain(taks1.s(id), task2.s())
my_process()
end = datetime.now()
return ['ENDED IN',(end-now).total_seconds()]
Q1: How can I tell how long it takes for this task to complete from beginning to end? The result I get to (ENDED IN) doesnt reflect the truth because the chain is run in parallel and the results are a fraction of second.
Q2 is there any way to place a termination timeout in the event the entire process of background_task takes longer then 25 minutes?
I think you can use wraps from functools there is an answers to a similar question here: timeit-versus-timing-decorator. #jonaprieto gives an example of using wraps in the link, I have reproduced below. This should allow you to achieve what you want.
from functools import wraps
from time import time
def timing(f):
#wraps(f)
def wrap(*args, **kw):
ts = time()
result = f(*args, **kw)
te = time()
print 'func:%r args:[%r, %r] took: %2.4f sec' % \
(f.__name__, args, kw, te-ts)
return result
return wrap
in an example:
#timing
def f(a):
for _ in range(a):
i = 0
return -1
Invoking method f wrapped with #timing:
func:'f' args:[(100000000,), {}] took: 14.2240 sec
f(100000000)
For this, I use timedelta, it returns the difference between two datetime arguments.
import datetime
start_at = datetime.datetime.now()
# do your thing!
end = datetime.timedelta(seconds=(datetime.datetime.now() - start_at).total_seconds())
With this code, when you print(end) it will return a result like 0:00:00.253998
I have a program that has multiple methods. I would like to measure how long it takes for each method to run when they are called.
For example
def func1:
blah
def func2:
blah
def main:
call func1 and func2 and measure their times
is there an easy way to do it.
I find the following piece of re-usable code handy when testing functions.
import timeit
def timed_function(f, *args, **kwargs):
myname = str(f).split(' ')[1]
def new_func(*args, **kwargs):
timer1 = timeit.default_timer()
result = f(*args, **kwargs)
timer2 = timeit.default_timer()
delta = timer2 - timer1
print('Function {} Time = {:6.3f}ms'.format(myname, delta*1000))
return result
return new_func
You can use it to decorate any function and then it will print the original function's name and execution time every time you run it.
Something like this:
#timed_function
def func1():
return sum([0.5 for i in range(10000)])
y = func1()
Code output:
Function func1 Time = 0.849ms
[I got the idea from here.]
Here's a code timing setup I wrote for myself, I use python 2.7
#!python2
import timeit
runs = 100
totalTime = 0.0; average = 0.0
testTimes = []
for i in range(runs):
startTimer = timeit.default_timer()
# >>>>> code to be tested goes here <<<<<
endTimer = timeit.default_timer()
timeInterval = endTimer - startTimer
testTimes.append(timeInterval)
totalTime += timeInterval
# running below statement causes each run longer to complete
# print '\n', '%1.4f' % timeInterval + ' seconds'
print
print ' Total time:', '%1.4f' % totalTime + ' seconds'
print 'Shortest time:', '%1.4f' % min(testTimes) + ' seconds'
print ' Longest time:', '%1.4f' % max(testTimes) + ' seconds'
print ' Average time:', '%1.4f' % (totalTime / runs) + ' seconds'
If you're running code from a separate file, perf_counter is the way to go. For example,
from time import perf_counter
def main():
start = perf_counter()
# Do stuff.
print(perf_counter() - start)
If you're testing code in the shell, there's an even easier way: the timeit module. It has two main functions: timeit and repeat. The former is simply a timer, the latter returns a list of times for different trials. https://docs.python.org/3/library/timeit.html?highlight=timeit#module-timeit
Just make sure to pass globals() as the globals argument if you're using imported functions!
currently i'm using the below code to find elapsed time for any routine/functions that i manually use start time and end time all that
But, i want a fuction should automatically return the entire function took how long as if like when we run query and it use to say how many seconds and milli seconds like that i want to run any function and each function should return me with that elapsed time.
and here is my code and absolutely i'm not happy with this and i want a high end professional line of code's pls help. Thanks.
def ElaspedTime(stime,etime):
from datetime import timedelta
timediff = timedelta(seconds=etime - stime)
return timediff
def STime():
return time.monotonic()
def ETime():
return time.monotonic()
#start_time = time.monotonic()
##call functions here
#end_time = time.monotonic()
#print( ElaspedTime(start_time,end_time))
You can create a wrapper function like this:
def runWithTime(f,*args):
from datetime import timedelta
import time
stime = time.time()
r = f(*args)
etime = time.time()
timediff = timedelta(etime - stime)
print timediff
return r
def a(x,y):
return x+y
r = runWithTime(a,1,2)
print r
write a decorator as follow (replace log.debug with print ...):
from functools import wraps
def with_stopwatch(f):
#wraps(f)
def wrapped(*args, **kw):
tstart = time()
result = f(*args, **kw)
tend = time()
log.debug('>>> func:%r took: %2.4f sec' % (f.__name__, tend - tstart))
return result
return wrapped
#with_stopwatch
def function()
...
I have a python code snippet that allows me to time function as a decorator. I would like to add function name to the output. and time in milli-seconds
def func_timer(func):
def f(*args, **kwargs):
start = time.time()
results = func(*args, **kwargs)
print "Elapsed: %.6fs" % (time.time() - start)
return results
return f
Usage is:
#func_timer
def foo():
pass
Current Output is :
Elapsed: 0.005168s
Output desired:
foo Elapsed: 5.168ms
Function objects have a __name__ attribute, you can use that. Simply multiply the time by 1000 if you want milliseconds:
print "%s Elapsed: %.6fms" % (func.__name__, (time.time() - start) * 1000)