-1

Let's say I have the following function, which takes x and y.

def calculate(x, y):
    return sin(x)**3 + y

In my use case, I call the function very often but mainly change y and x only once in a while. Since my function is computationally intense I would like to speed it up. Of course, I could restructure the complete code so that nothing gets calculated multiple times, but the added speed would not justify the added complexity.

I recall there was something for exactly this but I cannot remember what it was (maybe functools or some decorator?).

Jonathanthesailor
  • 159
  • 1
  • 1
  • 8
  • 1
    Looking for https://docs.python.org/3/library/functools.html#functools.cache or https://docs.python.org/3/library/functools.html#functools.lru_cache? – Iain Shelvington Aug 05 '22 at 09:05

2 Answers2

2

The cache decorator from functools is ideal for this. The caching mechanism is also known as memoization.

The implementation of a cache is straightforward. Think of it as a dictionary with keys constructed from the parameters passed to the function. Unless there's some kind of random component involved in the function implementation then the return value would be the same every time.

This means that by simply looking up the "key", the return value can be deduced without actually executing the function code.

Therefore:

from functools import cache
from math import sin

@cache
def calculate(x, y):
  return sin(x)**3 + y

Don't be tempted to use this decorator for every function however. Consider this:

@cache
def calculate(x, y):
  return x + y

Of course, this works BUT there's a small overhead in terms of the cache implementation which, in this particular case, would mean that use of the cache actually slows down the response

DarkKnight
  • 19,739
  • 3
  • 6
  • 22
  • Thanks for your explanation. This only works if the same parameters are given as before, right? Let's say, I repeat the calculation 10 000 times, with different x, and y doesn't change. In that case, the cache won't help anything. – Jonathanthesailor Aug 07 '22 at 13:43
  • @Jonathanthesailor Yes - that's exactly the point – DarkKnight Aug 07 '22 at 13:44
  • Sorry, pressed enter before my response was finished :D – Jonathanthesailor Aug 07 '22 at 13:45
  • would something like this help, or does the cache get deleted outside of the function? def calculate(x, y): @cache def inner_calc(x): sin(x)**3 return inner_calc(x) + y Btw. is there any way to put code in comments? – Jonathanthesailor Aug 07 '22 at 13:48
  • @Jonathanthesailor What would be the point/advantage in that? – DarkKnight Aug 07 '22 at 18:54
  • Oh, I see, my explanation was stupid. Y should change all the time, but x stay the same. The advantage would be, that sin(x)**3 would only be calculated once, and not everytime calculate(x, y) is called. Of course only, if the inner cache stays alive after the function is closed. – Jonathanthesailor Aug 08 '22 at 14:03
1

In order to save time and computation power, I recommend you use functools module.

The functools module is a cache module in python that gives you the ability to cache the result of your functions.

cache is a decorator that helps in reducing function execution for the same inputs using the memoization technique.

from functools import cache

@cache
def calculate(x, y):
    return sin(x)**3 + y
Jamiu S.
  • 5,257
  • 5
  • 12
  • 34
  • 1
    This answer is great, but please elaborate a bit more – Riccardo Bucco Aug 05 '22 at 09:13
  • Ok Riccardo Bucco I added some simple explanation to my answer. And thanks for drawing my attention to that. there are other features of functools you might be interested as well so I choose to add the following link in case you want to check on them [functools doc](https://docs.python.org/3/library/functools.html#module-functools) – Jamiu S. Aug 05 '22 at 09:35