Skip to content
Kavachकवच

Many Things at Once

● Advanced3 minBefore this: Tasks, Lists: map, filter, sumSpec 9.3

list.parallel_map(f, max: n) runs f on every item in tasks of their own, at most n at a time, and gives the results in the list's order.

fn square(n: Int) -> Int {
    n * n
}

fn main() {
    const results = [1, 2, 3, 4].parallel_map(n => square(n), max: 2)
    print(results)
}

The program ran and printed:

kavach run many.kav

[1, 4, 9, 16]
many.kav: Kavach code, then what running it prints

The results come back in the list's order, whichever task finishes first. Here the later pages finish first, yet the list is in order:

use std.time

fn fetch(n: Int) -> String uses Clock {
    time.sleep_ms(100 - n * 20)
    "page {n}"
}

fn main() {
    const pages = [1, 2, 3, 4].parallel_map(n => fetch(n), max: 4)
    print(pages)
}

The program ran and printed:

kavach run order.kav

["page 1", "page 2", "page 3", "page 4"]
order.kav: Kavach code, then what running it prints

max keeps a program polite to a server: urls.parallel_map(download, max: 10) never has more than 10 downloads going at once. Without it, every task starts at once.

Each task runs as spawn thread makes it (How Tasks Run), so in a release build the items compute on several cores at once. In the benchmark, eight sums of 150 million rounds each take 210 ms with parallel_map — and 164 ms with plain map, because each of these sums is a math loop that already runs on all cores by itself. parallel_map is for items that can't spread themselves like that: downloads, files, work of uneven sizes.

When an item fails or panics

Given a function that can fail, parallel_map fails with the first error in the items' order. A panic in an item's task is printed when it happens, as any task's is, and is then a panic where parallel_map was called: the call can't fail by its type, so there is no error to give back.

fn main() {
    print([4, 2].parallel_map(n => 8 / n))
    print([4, 0, 2].parallel_map(n => 8 / n))
}
src/main.kav: Kavach code
terminal
kavach run src/main.kav
[2, 4]
panic: division by zero
  at src/main.kav:3
panic: an item of `parallel_map` panicked: division by zero at src/main.kav:3
  at src/main.kav:3
tested