#!/usr/bin/env python
# encoding: utf-8
"""Test the speed of different kinds of for loops over lists of tuples.
The general_test_function can be used to test the execution time of any number of functions.
"""
def test_speed_of_for_loop_with_tuples():
"""This function tests the speed of two different for loops to see, if there's a difference.
Result: There is no big difference between the two approaches.
One run: [0.14503340959548949, 0.16319561004638672]
Another run: [0.12981771707534789, 0.14054121494293212]
Factor on another run: 1.1451155855
That's about 14 percent longer execution time for the loop which selects the second item inside the loop.
On 3 more runs, I got factors between 4% and 10%
TODO: Test, if the factors are related to the numbers inside the tuples.
TODO: Test, if a test with Strings comes to the same result.
"""
# We need random numbers, so we can create unoptimizeable lists.
from random import random
# Now we need an empty list.
many_tuples = []
# Which we fill with 100.000 tuples of random numbers.
for i in range(100000):
many_tuples.append((random(), random()))
# Now we get to the real test.
# We just call the functions in our test function :)
# For this we first create a list of functions we want to test.
list_of_functions = [loop_which_directly_calls_each_tuple_item, loop_which_calls_the_whole_tuple_and_then_selects_the_second_item]
# And pass it to the general test function with our arg, 10 times.
# Results is a list of lists of tuples.
results = []
for i in range(10):
results.append(general_test_function(list_of_functions, many_tuples))
# Calculate the mean
mean_time = []
# Work on each result
for i in results:
# Get the times of this result as list.
times_list = []
# Work on each function inside the single run to gets its time
for j in i:
# Append the time to the times_list.
times_list.append(j[0])
# Now add the times in the times list to the mean_time.
# If the times_list has a different length than the mean_time list, this should be the first run. We need to append the times.
if len(times_list) != len(mean_time):
for i in times_list:
mean_time.append(i)
# Else, this is a following run, so we can just add to each element.
else:
for i in range(len(times_list)):
mean_time[i] += times_list[i]
# Now we divide each element inside the mean_time by the number of runs (the len of the results.
for i in range(len(mean_time)):
mean_time[i] = float(mean_time[i]) / len(results)
return mean_time # TODO: Calculate the standard deviation, so we know how certain the result is.
def loop_which_directly_calls_each_tuple_item(many_tuples):
"""Call each item directly in the loop and return a list of the second item.TODO: Test, if it makes a difference if we call the first or the second item"""
second_items = []
for i, j in many_tuples:
second_items.append(j)
return second_items
def loop_which_calls_the_whole_tuple_and_then_selects_the_second_item(many_tuples):
"""Call the whole tuple in the loop and then select the second item when assigning."""
second_items = []
for i in many_tuples:
second_items.append(i[1])
return second_items
def general_test_function(functions, *args):
"""Compare the execution speed of different functions in the list of functions
@functions: [function1, function2, ...].
@*args: The argument(s) to pass to each of the functions. All functions get all and the same argument(s)"""
# We need the current time in seconds
from time import time
# First evaluate how long Python takes to get two times. We need to substract this value from the result to remove a constant offset.
# Get the current time two times
start_time = time()
finish_time = time()
# Now calculate the difference which is how long Python takes for getting the time.
#: The offset due to getting the time two times. This is less than 1*10e-5 s for me.
time_offset = finish_time - start_time
# Get start and stop times of all functions and put them into a list of tuples: (time_needed, function) - time needed first, so we can sort easily.
#: A list of functions with execution speed
execution_times = []
for i in functions:
# Start time of the function.
start_time = time()
# Execute the function with the given argument
i(*args)
# Get the finish time
finish_time = time()
# Get the difference
time_needed = finish_time - start_time - time_offset
# append the tuple of execution time and function to the list of execution_speeds.
execution_times.append((time_needed, i))
# Return the list of execution times, sorted by functions.
return execution_times
### Self-Test ###
if __name__ == "__main__":
# Test the speed for loops with tuples.
# 10 times.
print "10 Speedtests of for loops."
for i in range(10):
result = test_speed_of_for_loop_with_tuples()
# print result
# The factor can only be done this simply for testing two functions.
factor = result[1] / result[0]
print "Faktor:", factor
# Test mother sorting code.
# mothers = {"mother1": ["child1", "child2"], "mother2": ["child3"], "mother3": [], "mother4": [1, 2, 3]}
# print sort_by_children(mothers)
# print mothers
# Or just do nothing.
pass