Package: whatifmachine
The WhatIfMachine is a Python profiler which allows you to see what would happen to a profile if its functions ran in different amounts of time.It officially supports 3.6 – 3.8.QuickstartGet the WhatIfMachine fromPyPI:$ pip install whatifmachine --user --upgradeUse it to profile a script with arguments:$ whatifmachine script.py arg1 arg2 arg3FullstartHere’s a little scripttest.py:def f(n):
    for i in range(5):
        h(n)
        try:
            g(i + n)
        except ValueError:
            pass

def g(n, k=100_000):
    n = h(n, k)
    if n < 10**30106:
        raise ValueError('n is too small')
    return n

def h(n, k=100_000):
    for _ in range(k):
        n = 2 * n
    return n

f(1000)We can profile this using the WhatIfMachine:$ whatifmachine -f test test.py
         19 function calls in 4.189 seconds

   Ordered by: standard name
   List reduced from 6 to 4 due to restriction <'test'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        5    0.011    0.002    2.112    0.422 test.py:11(g)
       10    4.178    0.418    4.178    0.418 test.py:17(h)
        1    0.000    0.000    4.189    4.189 test.py:2(<module>)
        1    0.000    0.000    4.189    4.189 test.py:2(f)Note that we use the-ftestoption to filter the output to only show lines matchingtest.But WhatIfMachine provides thewhatif(...)decorator, which can be used to change how a function appears when profiled.
For example, we can add the decorator with thefactor=0.5argument tog:@whatif(factor=0.5)
def g(n, k=100_000):
    n = h(n, k)
    if n < 10**30106:
        raise ValueError('n is too small')
    return nThis allows us to see what the impact would be ifgonly took half the time to run:$ whatifmachine -f test test.py
         41 function calls in 3.049 seconds

   Ordered by: standard name
   List reduced from 14 to 4 due to restriction <'test'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        5    0.004    0.001    1.030    0.206 test.py:10(g)
       10    3.044    0.304    3.044    0.304 test.py:17(h)
        1    0.000    0.000    3.049    3.049 test.py:2(<module>)
        1    0.000    0.000    3.049    3.049 test.py:2(f)So we can see that makingg100% faster would only make the script 37% faster.
By comparison, the WhatIfMachine allows us to discover that the same effect can be achieved by makinghjust 40% faster.This is the impact ofAmdahl’s law.
So although the WhatIfMachine can’t actually make your code run any faster, it can indicate where investing your effort in optimising your code can have the biggest payoff.DecoratorThe WhatIfMachine’swhatifdecorator can be given any function that maps floats to floats, for example@whatif(lambda x: x*x).
Before this it also applies (in order):a maximum amount of time that the call would take (@whatif(maximum=0.1))a multiplicative factor (@whatif(factor=0.9))an additive bias (@whatif(bias=-0.05))These can be combined.
For example, suppose a function is decorated with@whatif(abs, factor=2,bias=-0.1).
Then the WhatIfMachine reportstseconds passing within this function asabs(2*t - 0.1)seconds, whatever use that is.Be careful, there is nothing to stop you from distorting time in a way which results in functions appearing to take zero or even a negative amount of time to run.
Good luck understanding those profile reports.External LinksPyPIGitHub