Hacker News new | ask | show | jobs
by z1mm32m4n 2612 days ago
Who's to say we couldn't use the types to make the runtime faster in the future?

One of the reasons why Sorbet does both runtime checking[1] more than just static checking is so that we can know that signatures are accurate, even when a typed method is called from untyped code.

If the signatures are accurate, a future project could take advantage of method's signatures to make decisions about how the code should actually be run. If the signatures lie, then any runtime optimization made using the types would only be overhead, because the runtime would have to abort the optimization and fall back to just running the interpreter.

[1]: https://sorbet.org/docs/runtime

3 comments

Well I am skeptical about performance improvements due to type annotations as well. Other languages have similar different systems and didn't get faster.

Dart had gradual types but didn't enforce them at runtime because of performance. The PyPy devs don't believe that type annotations help them for performance (http://doc.pypy.org/en/latest/faq.html#would-type-annotation...). Also there is no JS engine that uses TypeScript annotations so far to improve performance.

Types are usually on the wrong boundary: e.g. Integer doesn't state whether that value fits into a register or is a Bignum.

Also: Aren't some type checks quite expensive? So more expensive than a simple map/class/shape check? E.g. passing an array from untyped code to a signature with something like `Array<Integer>`. Wouldn't a runtime that verifies signatures have to check all elements in the array to be actual Integers?

It's because PyPy relies on traced runtime statistics for optimizations via inlining. There's another approach where you translate your typed program into a lower-level target language and compile it into a native binary. See https://github.com/mypyc/mypyc and https://github.com/cython/cython/wiki/Python-Typing-Proposal
Dart has long changed.
True, that's why I wrote "Dart had".
I work on an alternative Ruby implementation, and it looks like I'll be able to take these type definitions and use them to add extra type constraints to my intermediate representation very easily - just insert a type constraining node around each expression that's annotated with a type. It'll remove extra guards and increase performance, so should definitely be an option.
Thank you chris for all your work on Truffle! Looking forward to using it.
I programmed C back in my high school years 14+ years ago. Today I am mostly using JS because it is the cash crop of the industry, and it made me quite some money when I was away from electronics business (my main occupation) for a year after getting troubles with Canadian visas.

To me, it feels that there is a very thick wall in between high level languages and something with raw data access like C, C++, and D. You either completely throw out every convenience feature, or go all in on them.

In C, a lot of data access turns into single digit number of load/store or register access instructions. It is easy to see that it is close to impossible to add fancy data access functionality on top of that without going from single cycles to kilocycles.

I was once told "when your try improving a programming language performance, it eventually turns into C"

P.S. on JIT - it is not given that a JIT language be automatically faster than a well written interpreter on a modern CPU. One of early tricks of making fast interpreters was to keep as much of interpreter in cache and data in registers as possible to benefit from more or less linear execution flow of unoptimised code in comparison to unpredictable flow of JIT made executable code. Today, with 16MB caches, I think the benefit of that will be even bigger.

> I was once told "when your try improving a programming language performance, it eventually turns into C"

Which is kind of ironic given how bad C compilers generated code during the mid-80s, versus other mainframe languages.

>To me, it feels that there is a very thick wall in between high level languages and something with raw data access like C, C++, and D.

That is why we need something that offer 80% the Speed of C, 80% of Simplicity / expressiveness of Javascript / Ruby, and 80% of ease of long term maintenance of a functional PL like Ocaml.

I actually think Java will one day evolve very close to that goal.

Types are the means of "improving language performance" without turning into C. It's all about encoding invariants for the optimizer.

I doubt a competent JIT is ever slower than a competent interpreter, but it may not be that much faster or worth the workload.

It depends on the size of the primitives. An array language could be close to 1:1, while for a cpu-level instructions you will struggle to reach 1/6 of JITted perf.

You forget this is ruby, which will not have a competent JIT. They have such a bad JIT with enormous overhead that only very special cases will be faster, most cases are slower and will wait for locks or be racy.