# Going Parallel with concurrent.futures¶

Parallel computation can be implemented via the concurrent.futures module. The module is part of the standard library since Python `3.2`

.

Let's look at a simple example.

```
from time import sleep
def slow_function(x):
print('start: {}'.format(x))
sleep(5)
print('done: {}'.format(x))
return x**2
```

We defined `slow_function`

, a function simulating a heavy computation (taking 5 seconds). We now run it in the most straightforward way.

```
numbers = range(4)
for n in numbers:
slow_function(n)
```

So, the functions are done one at a time as expected. Let's measure how long this take.

```
import time
numbers = range(4)
start_time = time.time()
for n in numbers:
slow_function(n)
print(time.time() - start_time, 'seconds')
```

It takes `20`

seconds to run `4`

functions. The reason is they are all run on one single core. Now, we refactor the execution, and we make it **parallel**.

```
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor() as executor:
for n in numbers:
f = executor.submit(slow_function, n)
```

I am running these lines on a **dual-core** laptop. You can see that, indeed, the two cores are used simultaneously. The first two iterations are launched at the same time. Now, how much time do you expect we saved?

```
start_time = time.time()
with ProcessPoolExecutor() as executor:
for n in numbers:
f = executor.submit(slow_function, n)
print(time.time() - start_time, 'seconds')
```

Nice, the run-time was halved. It makes sense as we splitted the computation across two cores.