Track execution time in python - python-3.x

I want to know how long my code takes to run and have tried using the following code which was found on a different thread.
import time
start_time = time.time()
# my code
main()
print("--- %s seconds ---" % (time.time() - start_time))
but it does not seem to print the time it takes. I've included pictures of my code since the code is fairly long. Is there something I'm doing wrong?

You might have a bug in your code, because this works:
def dosomething():
counter = 10
while counter > 0:
counter -= 1
print ('getting ready to check the elapsed time')
def main():
start_time = time.time()
dosomething()
print("--- %s seconds ---" % (time.time() - start_time))
if __name__ == "__main__":
main()

Related

How to combine QTimer with QThreadPool to get real-time?

I am trying to put a QTimer inside a QThreadPool.
The reason is that I need to count real-time since the start of a process (recording video), but the actual code seems to be lagging a bit and the time counted is far from real-time.
However, when trying to create a minimal example, I ran into a different problem: QTimer cannot run with a QThreadPool ! (There is already multiple threads going on in the actual code.)
So two questions:
1- How do You use QTimer with multiple threads, aka QThreadPool ?
2- Would that be the best way to get real-time from the start of an "heavy" process ?
Here is my test code:
from PyQt5.QtCore import QTimer, QThreadPool
class Test():
def __init__(self):
self.timerthread()
print("Initialised")
# self.Timing()
def Timing(self):
self.Timer = QTimer()
self.Timer.moveToThread(self.threadpooltimer)
self.Timer.timeout.connect(self.UpdateTiming)
self.Timer.start(1) #per millisecond
self.msec = 0 % 1000
print("Timing is set")
def UpdateTiming(self):
self.msec += 1
self.msecd = self.msec % 1000
self.sec = self.msecd // 1000
self.secd = self.sec % 60
self.min = (self.sec // 60)
self.mind = self.min % 60
self.hour = self.min // 60
self.time = f'{self.hour:02}:{self.mind:02}:{self.secd:02}:{self.msecd:03}'
print(self.time)
def timerthread(self):
self.threadpooltimer = QThreadPool()
self.threadpooltimer.start(self.Timing)
print("Threading")
Test()
Thank You for your time!
For now, I think I managed to do it like this:
import time
start_time = time.perf_counter()
while True:
current_time = time.perf_counter() - start_time
timeoncams = "{:.3f}".format(current_time)
print(timeoncams)
The time seems accurate!

Why do HTTP calls in a for loop, without tasks or futures, not run faster with aiohttp?

In the following article about making HTTP requests with asyncio it states that snippet A takes 8 seconds to complete vs. snippet B which takes 1 second to complete.
I'm confused though why A isn't faster.
If aiohttp 'can make connections with up to 100 different servers at a time' (as stated in the article), wouldn't it effectively make the first 100 requests concurrently, and then the next 50 concurrently, resulting in a time much faster than 8 seconds and closer to B's time?
If not, where is the time lag coming from then?
A
import aiohttp
import asyncio
start_time = time.time()
async def main():
async with aiohttp.ClientSession() as session:
for number in range(1, 151):
pokemon_url = f'https://pokeapi.co/api/v2/pokemon/{number}'
async with session.get(pokemon_url) as resp:
pokemon = await resp.json()
print(pokemon['name'])
asyncio.run(main())
print("--- %s seconds ---" % (time.time() - start_time))
B
async def main():
async with aiohttp.ClientSession() as session:
tasks = []
for number in range(1, 151):
url = f'https://pokeapi.co/api/v2/pokemon/{number}'
tasks.append(asyncio.ensure_future(get_pokemon(session, url)))
original_pokemon = await asyncio.gather(*tasks)
for pokemon in original_pokemon:
print(pokemon)
asyncio.run(main())
print("--- %s seconds ---" % (time.time() - start_time))
The B example runs faster because asyncio.gather runs asyncio task concurrently, on the other hand A example runs it one by one, hereby new request is not created until the previous is finished.
Also you can rewrite the B example in much shorter way, since you do not need to use asyncio.ensure_future, asyncio.gather do all the stuff. Note that in latest versions of Python you should you asyncio.create_task instead of asyncio.ensure_future
import aiohttp
import asyncio
from typing import Any
async def get_pokemon(number: int, session: aiohttp.ClientSession) -> Any:
url = f"https://pokeapi.co/api/v2/pokemon/{number}"
async with session.get(url) as resp:
pokemon = await resp.json()
return pokemon
async def main():
async with aiohttp.ClientSession() as s:
# better use return_exceptions, otherwise if one failed you get app crash
original_pokemon = await asyncio.gather(*[get_pokemon(i, s) for i in range(1, 5)], return_exceptions=True)
for pokemon in original_pokemon:
print(pokemon)
print("*" * 10)
if __name__ == '__main__':
asyncio.run(main())
THE ADDITION:
The author of the article provides false information, the difference is caused by aiohttp.ClientSession which do some caching, presumably DNS lookups. Rewrite sync example with requests.Session and you'll get the same results as you have for async version. Actually if you do not use advantages of async execution model, you code could be even slower due to the loop and coroutines management.
Async:
import aiohttp
import asyncio
import time
start_time = time.time()
async def main():
async with aiohttp.ClientSession() as session:
for number in range(1, 100):
pokemon_url = f'https://pokeapi.co/api/v2/pokemon/{number}'
async with session.get(pokemon_url) as resp:
pokemon = await resp.json()
print(pokemon['name'])
asyncio.run(main())
print("--- %s seconds ---" % (time.time() - start_time))
# I got --- 11.73325777053833 seconds ---
Sync
import requests
import time
start_time = time.time()
# pay attention that I add with requests.Session() as session:
with requests.Session() as session:
for number in range(1, 100):
url = f'https://pokeapi.co/api/v2/pokemon/{number}'
resp = session.get(url)
pokemon = resp.json()
print(pokemon['name'])
print("--- %s seconds ---" % (time.time() - start_time))
# I got --- 12.19397759437561 seconds ---

How to control thread execution in Python3

Below python function executes after every 30 seconds, I would like to stop the thread execution after 1 hour (60 minutes) of total time. How can I get this ? Or polling is better than this ?
import time, threading
import datetime
def hold():
print(datetime.datetime.now())
threading.Timer(30, hold).start()
if __name__ == '__main__':
hold()
You could simply make use of the time module to do that in the following way
import time, threading
import datetime
def hold():
start = time.time()
while 1:
print(datetime.datetime.now())
# Sleep for 30 secs
time.sleep(30)
# Check if 1 hr over since the start of thread execution
end = time.time()
# Check if 1 hr passed
if(end - start >= 3600):
print(datetime.datetime.now())
break
if __name__ == '__main__':
# Initiating the thread
thread1 = threading.Thread(target=hold)
thread1.start()
thread1.join()
print("Thread execution complete")

why doesn't time passes the thread in python

I've created a code so at a certian time it has to display a message. I tried it with a counter and it worked, but when using "strftime" it doesn't work. Can any one explain what I did wrong.
Below you'll fine the code I used.
import datetime, threading, time
now = datetime.datetime.now()
def foo():
counter = 0
next_call = time.time()
while True:
#counter +=1
if(now.strftime("%H:%M:%S")>=("22:00:00")):
print("go to sleep")
time.sleep(30)
else:
print (datetime.datetime.now())
next_call = next_call+1;
time.sleep(next_call - time.time())
timerThread = threading.Thread(target=foo)
timerThread.start()
You never change the value of 'now'. Conseqeuently it is the fixed time at which you start running this program.
You need to update it inside the loop.

How to make my python code faster by using multi threading?

This is the only function in my program I am calling, and the argument 'apps' I am passing is directory which contains 5000 json files on which I will be doing some arithmetic and It take me around 25mins to process all the files.
Now I want to do same thing using multi threading to make it faster.
Can someone please help me with this.
def directory(apps):
for files in os.listdir(apps):
files_path = os.path.join(apps, files)
with open(files_path, 'r') as data_file:
#Doing some stuff
try:
time.sleep(1)
start_time = time.time()
directory(application)
print "===== %s seconds =====" % (time.time() - start_time)
except KeyboardInterrupt:
print '\nInterrupted'
print "===== %s seconds =====" % (time.time() - start_time)

Resources