0

If I am creating a program that does some complex calculations on a data set and I already know what some of the values should be, should I still calculate them? For example if I know that 0 or 1 would always be themselves should I just check if the value is 0 or 1 or actually do the calculations?

Edit:

I don't have code because I was asking as a concept. I was creating a program to return the base 10 log of each number in a data set and I was wondering if it would be more efficient to return values I already knew like 0 for 1, "undefined" for 0, and the number of zeros for numbers divisible by 10. I wasn't sure if it was more efficient and if it would be efficient on a larger scale.

Community
  • 1
  • 1
Joyal Mathew
  • 614
  • 7
  • 24
  • Can you give some example code? – Paul Rooney Oct 29 '18 at 02:48
  • 1
    So, something like this? `return x if x in [0,1] else complex_func(x)` – OneCricketeer Oct 29 '18 at 03:05
  • You seem to be talking about [memoization](https://en.wikipedia.org/wiki/Memoization) which is a method of optimization by re-using values that have already been computed. This has been [discussed here before](https://stackoverflow.com/questions/1988804/what-is-memoization-and-how-can-i-use-it-in-python). – Kapil Oct 29 '18 at 03:07
  • I think that would be an example of premature optimisation. Assuming you are using `math.log` your testing of special cases in Python is likely to take a relatively long time. Your average case will run longer, since any value that isn't a special case is running extra code. – John La Rooy Oct 29 '18 at 03:26

1 Answers1

1

Let's try this simple example

$ python3 -m timeit -s "from math import log; mylog=lambda x: log(x)" "mylog(1)"
10000000 loops, best of 3: 0.152 usec per loop
$ python3 -m timeit -s "from math import log; mylog=lambda x: 0.0 if x==1 else log(x)" "mylog(1)"
10000000 loops, best of 3: 0.0976 usec per loop

So there is some speedup, however. All the non special cases run slower

$ python3 -m timeit -s "from math import log; mylog=lambda x: log(x)" "mylog(2)"
10000000 loops, best of 3: 0.164 usec per loop
$ python3 -m timeit -s "from math import log; mylog=lambda x: 0.0 if x==1 else log(x)" "mylog(2)"
1000000 loops, best of 3: 0.176 usec per loop

And in this case, it's better just to leave the wrapper function out altogether

$ python3 -m timeit -s "from math import log" "log(2)"
10000000 loops, best of 3: 0.0804 usec per loop
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
  • Would this be better when doing bigger calculations? Also, would checking more cases make it more efficient like using the number of 0's when the number is divisible by 10? – Joyal Mathew Oct 29 '18 at 16:10
  • 1
    @JoyalMathew, I think it's going to be hard to improve in the case of `log`. In the general case it's often possible to use a list or a dict to store the special/common values. If the computation takes longer than a dict lookup it can definitely be worthwhile. That is basically how memoization works. – John La Rooy Oct 30 '18 at 01:03