Skip to content

A comprehensive Python demonstration comparing different concurrent programming approaches for calculating averages of multiple data sets.

License

Notifications You must be signed in to change notification settings

mattsebastianh/concurrent_programming_2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Concurrent Programming Performance Comparison

A comprehensive Python demonstration comparing different concurrent programming approaches for calculating averages of multiple data sets.

πŸ“‹ Overview

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

🎯 Purpose

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)

πŸš€ Features

  • 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

πŸ“‹ Requirements

  • Python 3.7+ (for full asyncio support)
  • Standard library only (no external dependencies)

πŸ”§ Installation

git clone <your-repository-url>
cd concurrent_programming_2

πŸ“– Usage

Run the script directly to execute all four approaches:

python script.py

Expected Output

Sequential 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

Enabling Debug Output

To see detailed execution information, uncomment the debug lines in the code by removing the # from lines marked with # debug.

πŸ” Implementation Details

Sequential Programming

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

Asynchronous Programming

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

Threading

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

Multiprocessing

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

πŸ“Š Performance Analysis

Expected Results

  • Sequential: ~3 seconds (1 second Γ— 3 operations)
  • Async/Threading/Multiprocessing: ~1 second (parallel execution)

Key Insights

  1. Sequential approach serves as the baseline
  2. Async excels with I/O-bound operations
  3. Threading provides concurrency but is GIL-limited
  4. Multiprocessing offers true parallelism at higher cost

πŸŽ“ Educational Value

This project teaches:

When to Use Each Approach

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

Python Concurrency Concepts

  • Global Interpreter Lock (GIL) impact
  • Event loops and coroutines
  • Thread synchronization
  • Process communication overhead

πŸ”§ Customization

Modifying Test Data

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]

Adjusting Simulation Time

time.sleep(1)  # Change sleep duration
await asyncio.sleep(1)  # For async version

Enabling Debug Output

Uncomment lines marked with # debug to see detailed execution flow.

πŸ“ Project Structure

concurrent_programming_2/
β”œβ”€β”€ script.py          # Main implementation
β”œβ”€β”€ README.md          # This documentation
β”œβ”€β”€ LICENSE            # MIT License
└── project_brief.md   # Original project description

🀝 Contributing

Feel free to:

  • Fork the repository
  • Add new concurrency patterns
  • Improve performance measurements
  • Enhance documentation
  • Add more test scenarios

πŸ“œ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ”— References


This project serves as an educational resource for understanding concurrent programming patterns in Python.

About

A comprehensive Python demonstration comparing different concurrent programming approaches for calculating averages of multiple data sets.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages