Reputation: 11
I want to implement async method in the following code:
import time
def main(num):
num_list = []
for i in range(num):
num_list.append(i)
print("The number that is added in list is:", i)
time.sleep(2)
return num_list
def count():
start_time = time.time()
num_list = [3,5,2,8,2]
for i in num_list:
print("\nIn count() = ", i)
data = main(i)
print("Got data from main() = ", data)
time.sleep(2)
total_time = time.time() - start_time
print("The code took",total_time,"seconds to complete")
if __name__ == "__main__":
count()
This code takes 50s to complete. I tried to implement async method in this code but I was not able to succeed because I just started learning about it. Can you tell me how can I implement async method in this code.
Here's the code where I tried to implement async method:
import asyncio, time
from asgiref.sync import sync_to_async
@sync_to_async
def main(num):
num_list = []
for i in range(num):
num_list.append(i)
print("The number that is added in list is:", i)
time.sleep(2)
return num_list
def get_data(data_var):
try:
data_var.send(None)
except StopIteration as e:
return e.value
async def count():
start_time = time.time()
num_list = [3,5,2,8,2]
for i in num_list:
print("In count() :".format(i))
task1 = asyncio.ensure_future(main(i))
data = get_data(main(i))
print("In main() = {}".format(data))
await asyncio.sleep(2)
await task1
total_time = time.time() - start_time
print("The code took",total_time, "seconds to complete")
if __name__ == "__main__":
asyncio.run(count())
And I am not getting num_list as return value instead I am getting None.
Upvotes: 1
Views: 1225
Reputation: 445
If you can convert your main into async function, then it can be written as this.
import asyncio
import time
from loguru import logger
async def main(num):
num_list = []
for i in range(num):
num_list.append(i)
logger.info(f"The number that is added in list is: {i}")
await asyncio.sleep(2)
return num_list
async def count():
start_time = time.time()
num_list = [3,5,2,8,2]
task_list = []
for i in num_list:
logger.info(f"In count() = {i}")
task = asyncio.create_task(main(i))
task_list.append(task)
result_list = await asyncio.gather(*task_list)
for r in result_list:
logger.info(f"Got data from main() = {r}")
total_time = time.time() - start_time
logger.info(f"The code took {total_time} seconds to complete")
loop = asyncio.get_event_loop()
loop.run_until_complete(count())
If you can't convert the main function, threading is your best bet.
from concurrent.futures import ThreadPoolExecutor, as_completed
from loguru import logger
def main(num):
num_list = []
for i in range(num):
num_list.append(i)
logger.info(f"The number that is added in list is: {i}")
time.sleep(2)
return num_list
def count():
start_time = time.time()
num_list = [3,5,2,8,2]
with ThreadPoolExecutor(max_workers=5) as executor:
futures = {}
for k in num_list:
logger.info(f"In count() = {k}")
futures[executor.submit(main, k)] = k
for future in as_completed(futures):
logger.info(f"Got data from main() = {future.result()}")
time.sleep(2)
total_time = time.time() - start_time
logger.info(f"The code took {total_time} seconds to complete")
count()
Both will achieve the same goal in terms of overall execution time.
Upvotes: 1