Take the 2-minute tour ×

I'm working on a Scala-based analytics system (http://www.hiringthing.com), and I'm finding that I'm often asking myself the following question. Given a "pure" function with no side effects, if I hit that function twice with the same inputs, can I expect the compiler to reuse the value generated from the first run, or will it go through all the code again. Put another way, is the first example below more efficient than the second?

def add(x: Int, y: Int) = x + y * 10000000000

val a = add(1,2)



do_something( add(1,2) )
do_another_thing( add(1,2) )

If the compiler can indeed optimize the second case, are there limits to the complexity of the function?

What I want to do is avoid running certain math heavy functions multiple times just for the sake of programming convenience...


share|improve this question
javap could help peeking into the byte code produced by the compiler. I doubt though that the current compiler will do the optimisation, simply because without monads it's difficult to determine whether the code has any side effects, but I might be wrong. –  Vlad Gudim Sep 30 '10 at 22:08

3 Answers 3

up vote 9 down vote accepted

From what I've seen, the Scala compiler doesn't optimize that at all. The JVM may, if it can determine that the results won't change, but often it has no good way to know.

So, generally, if it's a trivial computation, it doesn't make a difference, both because it's trivial, and because the JVM can figure out that it only needs to do it once. If it's complicated, and speed is essential, you should use the val a = method unless you have benchmarks that demonstrate to you that the JVM is smart enough in this case.

Note that sometimes it feels awkward to place vals. There are two ways to get around this. First, note that almost anything can be replaced by the equivalent statement in braces, so the exceptions may be less often than you think. Also, this method may be useful in certain circumstances:

def reuse[A,B](a: A)(f: A => B) = f(a)
reuse(add(1,2))( a => { do_something(a); do_another_thing(a)})
share|improve this answer
Through long Lisp and Haskell tradition, that "reuse" function should probably be called "let" –  Dave Griffith Sep 30 '10 at 22:23
Yes, probably so. –  Rex Kerr Sep 30 '10 at 22:32

The scala compiler doesn't attempt to optimize any through calls to functions or methods, unless you specifically use the @inline annotation (and even that isn't gauranteed). That said, the JVM, and the Hotspot JIT compiler in particular, almost certainly will be able to inline the call to "add" in your examples, and will then be able to remove the resulting common-subexpressions.

As always when asking questions about performance and compiler optimizations, no answers should be taken as gospel without extensive, professional benchmarking. Past performance is no gaurantee of future returns. Contents may settle during shipping. If swelling persists after four hours, see your doctor. All models over 18.

share|improve this answer
You forgot the "or 21 where required". –  Daniel C. Sobral Sep 30 '10 at 23:24

Without an effect system, the compiler simply cannot decide to reuse method (or Function) return values.

As has been the case for most languages throughout the history of computing, it's up to you to remove redundancy from your algorithms.

share|improve this answer

Your Answer


