What is the term for storing calculation values ​​instead of recounting multiple times?

When you have code like this (written in java, but applicable to any similar language):

public static void main(String[] args) {
    int total = 0;
    for (int i = 0; i < 50; i++)
        total += i * doStuff(i % 2); // multiplies i times doStuff(remainder of i / 2)
}

public static int doStuff(int i) {
    // Lots of complicated calculations
}

You can see that there is room for improvement. doStuff(i % 2)returns only two different values: one for doStuff(0)odd numbers and one doStuff(1)for odd numbers. Therefore, you spend a lot of time calculating / power recalculating these values ​​every time you say doStuff(i % 2). You can improve this:

public static void main(String[] args) {
    int total = 0;
    boolean[] alreadyCalculated = new boolean[2];
    int[] results = new int[2];
    for (int i = 0; i < 50; i++) {
        if (!alreadyCalculated[i % 2]) {
            results[i % 2] = doStuff(i % 2);
            alreadyCalculated[i % 2] = true;
        }
        total += i * results[i % 2];
    }
}

Now it accesses the stored value, not the recalculation. It might seem silly to keep such arrays, but for cases like a loop, say i = 0, i < 500, and you check i % 32every time, or something like that, an array is an elegant approach.

? , .

+4
2
+4

(CSE). - .

CBroe, memoization, esp, alreadyCalculated. , , . memoization , . , , , , . ( 2 ^ 32 ).

if .

public class Optim
{
  public static int doStuff(int i) { return (i+5) << 1; }
  public static void main(String[] args)
  {

    int total = 0;
    int results[] = new int[2];

    // more interesting if we pretend the loop count isn't known to be > 1, so avoiding calling doStuff(1) for n=1 is useful.
    // otherwise you'd just do int[] results = { doStuff(0), doStuff(1) };

    int n = 50;

    for (int i = 0 ; i < Math.min(n, 2) ; i++) {
        results[i] = doStuff(i);
        total += i * results[i];
    }
    for (int i = 2; i < n; i++) { // runs zero times if n < 2
        total += i * results[i % 2];
    }
    System.out.print(total);
  }
}

, . sum(0..n) = n * (n+1) / 2, , () doStuff(0) ( ) doStuff(1) ( ). doStuff() , .

+1

Source: https://habr.com/ru/post/1614900/


All Articles