Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

There are lots of things in scala that make programming convenient and clear, but in the core speed paths  of the software we want to use programming idioms that result in the fastest possible code, on par with the fastest Java code for the same functionality. This section is a collection of hints on how to do that.

  • Use while loops - the other kinds of loops (foreach, map, flatmap, etc. ) turn into higher-complexity things.
  • Use if-then-else. Avoid match-case with pattern matching.   An exception may be very simple match cases, i.e., matching on character or integer values. Think of it this way: you know what it is turning into when compiled if you use if-then-else, so there will be no performance surprises.
  • Hoist out common sub-expressions, even small ones.
  • Maybe not Option - use the Maybe/One/Nope classes instead of Scala's option types.
  • Inlining - The @inline annotation can be used, but sparingly. It does slow compilation down a lot. A final method of a final class has a chance of being inlined if it has no overrides. This really only should be used on classes like the Maybe[T] class and other 'value classes' e.g., units-of-measure classes, etc.
  • Avoid allocation of objects such as return tuples (except pairs - special case see below), return case-class objects, etc. Modifying individual result locations within the object, and then asking for their values with small getter-like methods will be much more efficient. Return strings by filling in CharBuffers/StringBuilders. Return multiple values by accepting an argument the type of which is a trait having var slots that are filled in by the call
  • Avoid use of the synchronized (aka thread-safe) classes. So use StringBuilder, not StringBuffer.
  • 2-Tuples are optimized out if they are immediately destructured in the caller. So if def foo(x): (Int, Int); val (x, y) = foo(z), then no tuple allocation will be done.