A comprehensive Python demonstration comparing different concurrent programming approaches for calculating averages of multiple data sets.
This project implements and compares four different programming paradigms to solve the same computational problem: calculating the average of three lists of numbers. The implementation demonstrates the performance characteristics and use cases for each approach:
- Sequential Programming - Traditional synchronous execution
- Asynchronous Programming - Event-driven concurrency using async/await
- Threading - Concurrent execution using Python threads
- Multiprocessing - True parallel execution using separate processes
This educational project illustrates:
- When to use different concurrency models
- Performance trade-offs between approaches
- Practical implementation patterns
- The impact of Python's Global Interpreter Lock (GIL)
- Performance Timing - Accurate measurement of execution time for each approach
- Debug Information - Detailed logging of execution flow (commented out by default)
- Simulated I/O Operations - Uses sleep to demonstrate concurrency benefits
- Clean Comparisons - Side-by-side performance analysis
- Python 3.7+ (for full asyncio support)
- Standard library only (no external dependencies)
git clone <your-repository-url>
cd concurrent_programming_2Run the script directly to execute all four approaches:
python script.pySequential Programming Elapsed Time: 3.001234 seconds
Asynchronous Programming Elapsed Time: 1.002345 seconds
Threading Elapsed Time: 1.003456 seconds
Multiprocessing Elapsed Time: 1.004567 seconds
To see detailed execution information, uncomment the debug lines in the code by removing the # from lines marked with # debug.
def main_sequential(list1, list2, list3):
outcomes = [cal_average(ls) for ls in [list1, list2, list3]]- Processes each list sequentially
- Total time = sum of individual processing times
- Baseline for performance comparison
async def main_async(list1, list2, list3):
tasks = [cal_average_async(ls) for ls in [list1, list2, list3]]
results = await asyncio.gather(*tasks)- Uses
asyncio.gather()for concurrent execution - Ideal for I/O-bound operations
- Single-threaded but non-blocking
def main_threading(list1, list2, list3):
threads = [threading.Thread(target=cal_average, args=(lst,)) for lst in lists]
[t.start() for t in threads]
[t.join() for t in threads]- Creates separate threads for parallel execution
- Good for I/O-bound tasks
- Limited by GIL for CPU-intensive operations
def main_multiprocessing(list1, list2, list3):
processes = [Process(target=cal_average, args=(lst,)) for lst in lists]
[p.start() for p in processes]
[p.join() for p in processes]- Creates separate processes for true parallelism
- Not affected by GIL
- Higher overhead but better for CPU-bound tasks
- Sequential: ~3 seconds (1 second Γ 3 operations)
- Async/Threading/Multiprocessing: ~1 second (parallel execution)
- Sequential approach serves as the baseline
- Async excels with I/O-bound operations
- Threading provides concurrency but is GIL-limited
- Multiprocessing offers true parallelism at higher cost
This project teaches:
| Approach | Best For | Limitations |
|---|---|---|
| Sequential | Simple tasks, debugging | Slowest for concurrent work |
| Async | I/O-bound operations | Single-threaded |
| Threading | I/O-bound with shared state | GIL limitations |
| Multiprocessing | CPU-bound tasks | Higher memory overhead |
- Global Interpreter Lock (GIL) impact
- Event loops and coroutines
- Thread synchronization
- Process communication overhead
l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Customize these lists
l2 = [2, 4, 6, 8, 10]
l3 = [1, 3, 5, 7, 9, 11, 13]time.sleep(1) # Change sleep duration
await asyncio.sleep(1) # For async versionUncomment lines marked with # debug to see detailed execution flow.
concurrent_programming_2/
βββ script.py # Main implementation
βββ README.md # This documentation
βββ LICENSE # MIT License
βββ project_brief.md # Original project description
Feel free to:
- Fork the repository
- Add new concurrency patterns
- Improve performance measurements
- Enhance documentation
- Add more test scenarios
This project is licensed under the MIT License - see the LICENSE file for details.
- Python asyncio Documentation
- Python threading Module
- Python multiprocessing Module
- Understanding the GIL
This project serves as an educational resource for understanding concurrent programming patterns in Python.