[racket] Typed-Racket slow-down by more than factor of two

From: Vincent St-Amour (stamourv at ccs.neu.edu)
Date: Wed Oct 29 17:42:55 EDT 2014

At Wed, 29 Oct 2014 14:23:25 -0700,
Wayne Iba wrote:
> 
> I recently posted a question about interactions between a typed/racket
> module and an untyped module.  Asumu pointed me to a known problem in the
> contract system that has not yet been addressed.
> http://docs.racket-lang.org/guide/contracts-gotchas.html#%28part._.Mixing_set__and_contract-out%29
> 
> By adding getter functions for my provided variables, I was able to get the
> code working.  At this point, about one-fifth of my code is now typed.
> Unfortunately, this version is 2.5 times slower than the original.
> 
> So my questions:
> 1. Is this unsurprising?  Do I need to port *all* of my code before I can
> expect to see a speed-up?  (And until then can expect a slow-down?)

You don't necessarily need to port all of your code. Minimizing contract
boundary crossings should help, which you can do either by adding types
to modules, or by moving individual functions to different modules.
In general, you should avoid going between typed and untyped code within
hot code; better to stick to one or the other.

To know contract boundaries are especially problematic, you can use the
contract profiler. It should help you focus your efforts on the
highest-impact modules.

> 2. A number of my data structures use byte numbers.  Am I incurring a
> penalty using Byte and should instead use Index or some other numeric type?
> (My application hits memory limits so delaying that is important unless it
> is the case that using the smaller numbers costs many times more than the
> space required for larger number types.)

Contract checking for `Byte` and `Index` is more expensive than checking
for `Fixnum`. I'm not sure the difference would be significant, though.
The contract profiler could shed some light on that.

Using `Fixnum` may not enable as many optimizations, though, so it's a
tradeoff. You may want to try using the more restricted types
internally, but using `Fixnum` at the boundaries.

> 3. I'm doing a fair bit of mutation of byte strings and defined
> structures.  Could this explain the slow down in TR?

Byte strings should not be a problem. Do your mutable structures cross
between typed and untyped code? If so, there may be some proxying and
contract costs involved.

Do give the contract profiler a try. If it helps, please report back!

Vincent

Posted on the users mailing list.