You need to put one more thing in consideration: readability. Option 2 seems much more readable than option 1.
Apart of readability, in this example, I would go to Option 2 for a reason that I'll explain below.
Here is a representation of your code in Java and the bytecode produced:
public class Main {
public static int totalRevenue;
public static int totalProfit;
public static int option1(int numSold, int price, int cost) {
// Option 1 (memory)
totalRevenue += numSold * price;
totalProfit += numSold * price - numSold * cost;
return numSold * price;
}
public static int option2(int numSold, int price, int cost) {
// Option 2 (time)
int saleRevenue = numSold * price;
totalRevenue += saleRevenue;
totalProfit += saleRevenue - numSold * cost;
return saleRevenue;
}
}
Bytecode:
public class Main {
public static int totalRevenue;
public static int totalProfit;
public Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static int option1(int, int, int);
Code:
0: getstatic #2 // Field totalRevenue:I
3: iload_0
4: iload_1
5: imul
6: iadd
7: putstatic #2 // Field totalRevenue:I
10: getstatic #3 // Field totalProfit:I
13: iload_0
14: iload_1
15: imul
16: iload_0
17: iload_2
18: imul
19: isub
20: iadd
21: putstatic #3 // Field totalProfit:I
24: iload_0
25: iload_1
26: imul
27: ireturn
public static int option2(int, int, int);
Code:
0: iload_0
1: iload_1
2: imul
3: istore_3
4: getstatic #2 // Field totalRevenue:I
7: iload_3
8: iadd
9: putstatic #2 // Field totalRevenue:I
12: getstatic #3 // Field totalProfit:I
15: iload_3
16: iload_0
17: iload_2
18: imul
19: isub
20: iadd
21: putstatic #3 // Field totalProfit:I
24: iload_3
25: ireturn
}
For the sake of understandability, iload_* load data from stack and istore_* store data into stack.
So you can notice that you really saved one memory allocation, but you spend precious CPU cycles.
But here is the reason: Memory allocations work in blocks, not at byte level. Each time a thread runs, it will allocate a certain amount of memory to use in stack operations. So unless you are lucky enough to have these 4 bytes overflow memory allocation for this block (and requiring you to setup a larger stack size), you will be ending up spending the same memory amount to run both examples. But in the second one, you will spend more cycles doing math calculations.