Image by Egor Kamelev from Pexels

Python quick tip: DICT or IF for getting a value? Performance & memory battle within python standard modules.

Are you afraid of unknowns, and you always stay with only one way of implementation? Or you want to be a better python programmer?

Let me show you on why to use dict instead of if statements in your python program.

Background:

If statements and dicts are present in every modern programming language. Whereas if statements are especially designed to control flow of operations of a program, dicts are a data structures. Nevertheless, dicts may be used to control flow of operations the same as if statements, or even better!

Let’s see an example!

This is an example of if statement in python. We are going to print animal’s sound. So for example a cat’s sound is “miau” etc…

animals = ['cat', 'lion', 'puma']for animal in animals:
if animal == 'cat':
print('meow')
if animal == 'lion':
print('roar')
if animal == 'puma':
print('rrrr')

Now we are going to do the same with usage of a dict:

dict_example = {'cat': 'meow',
'lion': 'roar',
'puma': 'rrrr'}
for animal in animals:
print(dict_example[animal])

Both methods output the same — but which one is a better?

Let’s go to the battle:

The first step is to prepare a lot bigger dataset.

Note: for a small dataset the difference is so small that it’s no difference whether we use a dict or if statements.

# Data configuration
RANGE = 10000
WORD = 'value'
random_values = [randint(0, RANGE) for p in range(0, RANGE)]

As you can see above we generate 10k random integer values. This is used to have a random queries for both dict and if statement. (you will see in a moment).

Now we initialize empty lists to store values from our queries:

if_list = []
dict_list = []

Below we need to build a dict. For a key we set an integer from a RANGE (defined before) and as for value we set WORD (‘value’) + string of a key.

dict_test = {}
for key in range(0, RANGE+1):
dict_test[key] = WORD + str(key)

Now it’s time for a code to check performance. For memory profiling we are going to use tracemalloc. For timing, I used a simple python timer.

Dict code check:

# below we are checking a dict implementation
tracemalloc.start()
start = time.time()
for dict_value in random_values:
dict_list.append(dict_test[dict_value])
end = time.time()
first_size, first_peak = tracemalloc.get_traced_memory()

print("================ TIME & PEAK DICT =================")
print(end - start)
print(f"{first_size/1028=} mb, {first_peak/1028=} mb")

If statements code check:

Note: below code tries to mimic if statement in a loop. If a condition is not met, it adds + 1 and checks another if statement.

# below we are checking an ifs statements
start = time.time()
for if_value in random_values:
# uncomment below for validation purposes
# print(if_value)
condition = 0
if condition == if_value:
if_list.append(WORD)
continue
else:
for r in range(1, RANGE):
condition += 1
if condition == if_value:
# uncomment below for validation purposes
# print(if_value, condition)
if_list.append(WORD + str(condition))
break
end = time.time()
second_size, second_peak = tracemalloc.get_traced_memory()

print("================ TIME & PEAK IFs =================")
print(end - start)
print(f"{second_size/1028=} mb, {second_peak/1028=} mb")

Let’s see the results on 10k data points:

= TIME & PEAK DICT =
0.000997304916381836
first_size/1028=85.1750972762646 mb, first_peak/1028=85.22178988326849 mb

= TIME & PEAK IFs =
28.16986608505249
second_size/1028=657.0145914396887 mb, second_peak/1028=657.1429961089494 mb

As you can see a dict is faster 3000x times and consumes 7x less memory on the 10k range.

Here’s how it looks graphically on a range of values:

[10, 100, 500, 1000, 2000, 3000, 5000, 10000]
Legend:blue squares — dict 
red line — if statements

Now go and change your if statements in favour of a dict :) cheers!

Appendix 1: a complete code

import matplotlib.pyplot as plt
from random import randint
import time
import tracemalloc

# Data configuration
RANGE = 10000
ranges = [10, 100, 500, 1000, 2000, 3000, 5000, 10000]

if_list_time = []
if_list_memory = []
dict_list_time = []
dict_list_memory = []

for RANGE in ranges:
WORD = 'value'
random_values = [randint(0, RANGE) for p in range(0, RANGE)]

if_list = []
dict_list = []

dict_test = {}
for key in range(0, RANGE+1):
dict_test[key] = WORD + str(key)


# below we are checking a dict implementation
tracemalloc.start()
tracemalloc.clear_traces()

start = time.time()
for dict_value in random_values:
dict_list.append(dict_test[dict_value])
end = time.time()
first_size, first_peak = tracemalloc.get_traced_memory()

print("================ TIME & PEAK DICT =================")
print(end - start)
print(f"{first_size/1028=} mb, {first_peak/1028=} mb")

dict_list_time.append(end - start)
dict_list_memory.append(first_peak)

# clearing tracemalloc
tracemalloc.clear_traces()

# below we are checking an ifs statements
start = time.time()
for if_value in random_values:
# uncomment below for validation purposes
# print(if_value)
condition = 0
if condition == if_value:
if_list.append(WORD)
continue
else:
for r in range(1, RANGE):
condition += 1
if condition == if_value:
# uncomment below for validation purposes
# print(if_value, condition)
if_list.append(WORD + str(condition))
break
end = time.time()
second_size, second_peak = tracemalloc.get_traced_memory()

print("================ TIME & PEAK IFs =================")
print(end - start)
print(f"{second_size/1028=} mb, {second_peak/1028=} mb")

if_list_time.append(end - start)
if_list_memory.append(second_peak)

plt.figure(1)
plt.subplot(211)
plt.plot(ranges, if_list_time, 'r--', ranges, dict_list_time, 'bs')
plt.ylabel('time in seconds')
plt.xlabel('number of data points')

plt.subplot(212)
plt.plot(ranges, if_list_memory, 'r--', ranges, dict_list_memory, 'bs')
plt.ylabel('memory in kib')
plt.xlabel('number of data points')
plt.show()

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store