# Setting the Baseline

After all the theory on Python concurrency and the Python GIL, we are now ready for some example code and experiments. Let’s get to work!

## Our test function

Let’s first define a function that we can use to benchmark our different options. All the following examples use the same function, called heavy:

```def heavy(n, myid):
for x in range(1, n):
for y in range(1, n):
x**y
print(myid, "is done")```

The heavy function is a nested loop that does multiplication. It is a CPU-bound function. If you observe your system while running this, you’ll see CPU usage close to 100% (for one core). You can replace it with anything you want, but beware of race conditions — don’t use shared objects or variables.

We’ll be running this function in different ways and explore the differences between a regular, single thread Python program, multithreading, and multiprocessing.

## The baseline: single threaded execution

Each Python program has at least one thread: the main thread. Below you’ll find the single-threaded version, which serves as our baseline in terms of speed. It runs our heavy function 80 times, sequentially:

```import time

# A CPU heavy calculation, just
# as an example. This can be
# anything you like
def heavy(n, myid):
for x in range(1, n):
for y in range(1, n):
x**y
print(myid, "is done")

def sequential(n):
for i in range(n):
heavy(500, i)

if __name__ == "__main__":
start = time.time()
sequential(80)
end = time.time()
print("Took: ", end - start)```

On my system, this takes about 46 seconds to run to completion.

Note that the `if __name__ == "__main__":` part is required for this to work on Windows computers, but it’s good form to always use it.

In the following articles, we’ll explore a threaded version and a multiprocessing version and learn the difference between these two ways of writing concurrent code.
{"ft_lang_label":"__label__en","ft_lang_prob":0.86315024,"math_prob":0.88872564,"size":1834,"snap":"2021-43-2021-49","text_gpt3_token_len":428,"char_repetition_ratio":0.104371585,"word_repetition_ratio":0.08552632,"special_character_ratio":0.25136313,"punctuation_ratio":0.14248021,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.96416795,"pos_list":[0,1,2],"im_url_duplicate_count":[null,null,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2021-10-17T03:14:57Z\",\"WARC-Record-ID\":\"<urn:uuid:c42a5ad1-96df-4c18-be77-af794325752b>\",\"Content-Length\":\"76569\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:4902771d-6435-40b7-9e44-ac1e0329ef44>\",\"WARC-Concurrent-To\":\"<urn:uuid:946a2dfb-b88c-4314-8886-74112e13a21f>\",\"WARC-IP-Address\":\"172.67.153.187\",\"WARC-Target-URI\":\"https://python.land/python-concurrency/setting-the-baseline\",\"WARC-Payload-Digest\":\"sha1:AKMCBS3Z2WNJCKFKMNH6V4VVQUB3VY4Q\",\"WARC-Block-Digest\":\"sha1:GBS5I7PWX7SRSUSDANCKRLVQAY2KNRPY\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2021/CC-MAIN-2021-43/CC-MAIN-2021-43_segments_1634323585120.89_warc_CC-MAIN-20211017021554-20211017051554-00137.warc.gz\"}"}