#!/usr/bin/env python # coding: utf-8 # # Code Optimization and Execution Time # Open In Colab # ## finding actual running time of code - timeit # - timeit - measures execution time of small code snippets # - timeit.timeit(stmt='pass', setup='pass', timer=[default timer], number=1000000, globals=None) # - returns time in seconds # In[2]: import timeit help(timeit) # # Python code optimization # - https://wiki.python.org/moin/PythonSpeed/PerformanceTips # ## Summary # # - use functions and local variables instead of globals, eventhough function calls are relatively high # - avoid dot . member access specifier # - user built-in list.sort and sorted with key using itemgetter function if required # - avoid string concatenation; use "".join(somelist) instead # - use list comprehension and map() instead of loops # - while working with dict (esp. initializing), use try catch instead of key test # - use defaultdict class from collections # - doing stuff less often - change sys.setswitchinterval(sys.maxsize) to as high as possible if not running threads and catching signals # - use addition and subtraction instead of multiplicaiton and divisions # - avoid recursion; esp. if can't increase system's recursion limit # - sys.setrecursionlimit(10**6) # In[7]: import sys sys.getswitchinterval() # In[8]: # what is the mazsize of sytem sys.maxsize # In[9]: sys.setswitchinterval(100000) # In[10]: sys.getswitchinterval() # In[2]: import timeit # In[9]: code = ''' x = 47 x = x * 2 ''' timeit.timeit(stmt=code) # runs 1M times # In[10]: code = ''' x = 47 x = x << 1 ''' timeit.timeit(stmt=code) # runs 1M times # In[5]: code = ''' # x is local variable x = 47 x = x + x ''' timeit.timeit(stmt=code) # runs 1M times # In[4]: # x is global variable x = 47 code = ''' global x x = x + x ''' timeit.timeit(stmt=code, globals=globals()) # runs 1M times; takes ~12 seconds # In[59]: # printing some result n times # input and output are the major bottlenecks in execution time code = ''' import sys n = 100000 #100K takes 5.x seconds on my macbook pro 2019 for i in range(n): print(i**2) ''' timeit.timeit(stmt=code, number=1) # In[58]: # concatenating result into a string and printing once code = ''' n = 100000 # 100K takes 0.056 seconds on my 2019 macbook pro ans = '' for i in range(n): ans += str(i**2) print(ans) ''' timeit.timeit(stmt=code, number=1) # In[57]: # concatenating result into a string and printing once code = ''' n = 10000000 # 100K takes 0.050 seconds on my 2019 macbook pro ans = '' for i in range(n): ans += str(i**2) ''' timeit.timeit(stmt=code, number=1) # In[56]: # using list to collect answers and print once as string code = ''' n = 10000000 # 100K takes 0.055 seconds on my 2019 macbook pro ans = [] for i in range(n): ans.append(str(i**2)) #converting and appending string to list ans = ''.join(ans) #typically print before storing into a variable ''' timeit.timeit(stmt=code, number=1) # In[55]: # using list to collect int answers and print once as string # not a whole lot of difference compared to collecting string itself code = ''' n = 10000000 # 100K takes 0.055 seconds on my 2019 macbook pro ans = [] for i in range(n): ans.append(i**2) #appending int to list #map to string and join to print ans = ''.join(map(str, ans)) ''' timeit.timeit(stmt=code, number=1) # In[23]: def factorial_recurse(n): if(n == 0): return 1 return n * factorial_recurse(n - 1) # In[16]: sys.getrecursionlimit() # In[19]: factorial_recurse(3000) # In[20]: sys.setrecursionlimit(10**6) # In[22]: factorial_recurse(3000) # In[23]: timeit.timeit('factorial_recurse(3000)', number=1, globals=globals()) # In[24]: def factorial_iter(n): fact = 1 for i in range(1, n+1): fact *= i return fact # In[25]: factorial_iter(3000) # In[26]: timeit.timeit('factorial_iter(3000)', number=1, globals=globals()) # ## Time complexity # - Time complexity of various Python built-in data sturctures and functions # - https://wiki.python.org/moin/TimeComplexity