import asyncio import multiprocessing as mp import time from functools import partial from typing import Any, Dict, Union class HighSpeedExecutor: def __init__(self, num_processes: int = None): """ Initialize the executor with configurable number of processes. If num_processes is None, it uses CPU count. """ self.num_processes = num_processes or mp.cpu_count() async def _worker( self, queue: asyncio.Queue, func: Any, *args: Any, **kwargs: Any, ): """Async worker that processes tasks from the queue""" while True: try: # Non-blocking get from queue await queue.get() await asyncio.get_event_loop().run_in_executor( None, partial(func, *args, **kwargs) ) queue.task_done() except asyncio.CancelledError: break async def _distribute_tasks( self, num_tasks: int, queue: asyncio.Queue ): """Distribute tasks across the queue""" for i in range(num_tasks): await queue.put(i) async def execute_batch( self, func: Any, num_executions: int, *args: Any, **kwargs: Any, ) -> Dict[str, Union[int, float]]: """ Execute the given function multiple times concurrently. Args: func: The function to execute num_executions: Number of times to execute the function *args, **kwargs: Arguments to pass to the function Returns: A dictionary containing the number of executions, duration, and executions per second. """ queue = asyncio.Queue() # Create worker tasks workers = [ asyncio.create_task( self._worker(queue, func, *args, **kwargs) ) for _ in range(self.num_processes) ] # Start timing start_time = time.perf_counter() # Distribute tasks await self._distribute_tasks(num_executions, queue) # Wait for all tasks to complete await queue.join() # Cancel workers for worker in workers: worker.cancel() # Wait for all workers to finish await asyncio.gather(*workers, return_exceptions=True) end_time = time.perf_counter() duration = end_time - start_time return { "executions": num_executions, "duration": duration, "executions_per_second": num_executions / duration, } def run( self, func: Any, num_executions: int, *args: Any, **kwargs: Any, ): return asyncio.run( self.execute_batch(func, num_executions, *args, **kwargs) ) # def example_function(x: int = 0) -> int: # """Example function to execute""" # return x * x # async def main(): # # Create executor with number of CPU cores # executor = HighSpeedExecutor() # # Execute the function 1000 times # result = await executor.execute_batch( # example_function, num_executions=1000, x=42 # ) # print( # f"Completed {result['executions']} executions in {result['duration']:.2f} seconds" # ) # print( # f"Rate: {result['executions_per_second']:.2f} executions/second" # ) # if __name__ == "__main__": # # Run the async main function # asyncio.run(main())