3 ms·
Is typed racket still very slow? I'm interested in hearing how Racket's gradual typing works.
by bjourne 8y ago
Is typed racket still very slow? I'm interested in hearing how Racket's gradual typing works.
- Bogdanp 8y agoIt depends upon what you mean by slow. Typed Racket code compiles more slowly than normal Racket code, but should run about as fast or faster (for a small set of specifically-typed code[0]). [0]: https://docs.racket-lang.org/ts-guide/optimization.html https://docs.racket-lang.org/ts-guide/optimization.html
- chriswarbo 8y agoTyped racket isn't slow (as far as scripting languages go). Maybe you're thinking of Racket's "contract" system? AFAIK typed racket does type-checking during compilation (via raco); the resulting code is no slower than normal Racket, although I'm not sure if it's faster either. The contract system is different; it works on normal, untyped Racket code and performs checks at runtime; similar to using Python decorators to check the input and output of a function. This slows things down, so it's recommended to only check things at module boundaries. For example: #lang racket (require racket/contract) (require racket/match) (provide factorial) (define/contract (factorial n) (-> exact-nonnegative-integer? exact-nonnegative-integer?) (fact n)) (define (fact n) (match n [0 1] [_ (* n (fact (- n 1)))])) This module exposes the `factorial` function, which checks (at runtime) whether its argument and return value are non-negative integers (i.e. 0, 1, 2, ...). The actual calculation is done by the `fact` function, which is private and doesn't do any checks. If we don't separate the checks from the calculation, we would end up running the checks on every recursive call, which would slow things down a lot. As far as I'm aware, Racket's gradual typing is done by contracts at the interface between typed and untyped code. Hence it's not that typed racket is slow, it's that passing untyped values into typed functions can be slow, if we want accurate blame information for errors.
- bjourne 8y agoI'm referring to Takikawa et al (2016), who reported performance 50-100 times worse performance numbers by mixing typed and untyped Racket code together. Actually 100 times slower execution. They used type annotations on the module level. Would be interesting to know if Racket developers have proven them wrong and if so, how. http://www.ccis.northeastern.edu/home/types/publications/gradual-dead/pre-treatment.pdf http://www.ccis.northeastern.edu/home/types/publications/gra...
- maxiepoo 8y agoJust to make it clear, the authors of that paper (including myself) are all to some extent Racket developers. Some big improvements have been made but there are still pathological cases. For the latest published on this see this paper: http://users.cs.northwestern.edu/~robby/pubs/papers/oopsla2018-fgsfs.pdf http://users.cs.northwestern.edu/~robby/pubs/papers/oopsla20... But also it's important to note that it's not Typed Racket or Racket in isolation that are slow, but the inter-mingling of the two due to contract overhead.
- mruts 8y agoTakikawa is a core racket dev, I believe.
- chriswarbo 8y agoYes, that fits with my own experience. I've not used Typed Racket itself, but I've used contracts in untyped Racket. I found them so slow that I ended up using a macro which discarded them unless it was a run of the test suite. Figure 3 in that paper is enlightening: the fully typed version takes 0.7x as long as the untyped version, so Typed Racket is slightly faster than normal Racket. Most of the partially-typed versions take 50x to 100x as long, as you say, showing that it is indeed the contracts that slow everything down.