liveBook · Manning

Decomposition

As explained in Grokking Concurrency

Data decomposition is a parallel programming technique that partitions a collection of data into independent chunks and applies the same operation to each chunk.

Imagine clearing snow with a friend. With one shovel, taking turns adds waiting. If one person shovels while the other spreads salt, you have split the job by function. With two shovels, you could instead divide the area into zones and clear them independently. Decomposition looks for work that can proceed without waiting for other work. section 7.2 section 7.4

There are two main approaches. Task decomposition separates different functions, such as searching for emails and displaying them. Data decomposition divides a collection into chunks and applies the same operation to each chunk, such as checking separate groups of possible passwords. A dependency graph can help reveal which tasks are truly independent before execution details are considered. section 7.1 section 7.2 section 7.4

Turn a file-search loop into separate tasks

A sequential search checks files one after another for a word. Because checking one file does not require the result from another, each file can become a separate task. A Python ThreadPool can run those checks concurrently and collect the results. Reading files still involves I/O, so concurrent tasks are not guaranteed to process their data simultaneously. section 7.5

# Chapter 7/find_files/find_files_concurrent.py 
import os
import time
import typing as T
from multiprocessing.pool import ThreadPool

def search_file(file_location: str, search_string: str) -> bool:
    with open(file_location, "r", encoding="utf8") as file:
        return search_string in file.read()

def search_files_concurrently(file_locations: T.List[str],
                              search_string: str) -> None:
    with ThreadPool() as pool:                                         #1
        results = pool.starmap(search_file,                            #1
                               ((file_location, search_string) for     #1
                                file_location in file_locations))      #1
        for result, file_name in zip(results, file_locations):
            if result:
                print(f"Found string in file: `{file_name}`")

if __name__ == "__main__":
    file_locations = list(
        glob.glob(f"{os.path.abspath(os.getcwd())}/books/*.txt"))
    search_string = input("What word are you trying to find?: ")

    start_time = time.perf_counter()
    search_files_concurrently(file_locations, search_string)
    process_time = time.perf_counter() - start_time
    print(f"PROCESS TIME: {process_time}")

The Python listing uses ThreadPool.starmap to apply the same search function to different files, then pairs results with filenames. section 7.5

Choose chunk size with care. Too few large tasks can leave processing resources idle or give one worker most of the work. Many small tasks offer scheduling flexibility but increase coordination overhead. Aim for at least as many tasks as available processing resources, preferably more; then weigh that flexibility against overhead. Decomposition does not help when an algorithm offers no independent work. section 7.9 section 13.4

How Grokking Concurrency covers it

How deep it goes
Works through functional and data partitioning, dependency analysis, and granularity trade-offs; leaves execution details mostly outside the design focus.
Examples
Uses snow clearing, password candidates, email functions, and a Python file-search loop to contrast ways of dividing work.
What it assumes
Builds from a sequential file-search loop and its independent iterations before introducing a threaded version.
What you can do after
Practice/perform partitioning by finding independent work and choosing task sizes while accounting for load balance and coordination overhead.
How it connects
Links dependency graphs, task parallelism, loop-level parallelism, SIMD, and map/reduce to ways of finding or organizing concurrent work.

Also explained in

Compare how 10 books explain decomposition →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Grokking Concurrency. The section links point to the parts of the book it draws on.