Hacker News new | ask | show | jobs
by cmrdporcupine 1544 days ago
So I've been working on a personal project which is in a mix of C++ and TypeScript -- partially because of practicality and partially to learn TypeScript, and I'm really liking the language.

One question I have is whether there's any possibility that TypeScript could, in the long run, gain performance advantages over pure JS? That the compiler could leave behind some type information artifacts so that V8 (or similar) could use that information at runtime to optimize method dispatch and other operations?

Likewise with the flow pieces mentioned here, I gotta think that the VM could optimize out certain runtime checks on dispatch or conditional branching if it knows that the compiler has already checked for these?

3 comments

I really enjoy Typescript, but every time I use it I think to myself, this would be so much better if were built on top of something other than JavaScript. Maybe AssemblyScript or some other TS to WASM target will come along with a better underlying type system and a good standard library. Dare to dream.
Yep. Except that the base semantics of the language really are tuned for JavaScript. So I can't see a separation being feasible between the two.

It would have to be a new language, sharing maybe 90% of syntax etc. but differing in some places where interoperability with JS has forced compromises (base number types is one thing I can think of. I'd like separate int and floats, etc.) and, yeah, targeting WASM etc. And honestly, I'd be game for that. Esp if it came with performance advantages.

What you're describing is essentially the origin story for Dart.
Yes that's what I meant by proper type system - int, float, decimal... proper date/time/timezone support. To name a few :)
Not quite what you are dreaming for, but there's https://typescripttolua.github.io/
V8 already does this.

When you write your code in a way that is akin to what you would do in a static environment, V8 emits additional type checks, if these pass, then it will run your code through a optimized version of the code that makes certain assumptions about the data types in use. If these type checks fail, then V8 will deoptimize the function/code.

Deoptimization needs to happen because the assumptions made about the execution of the code was wrong and the optimized code cannot handle this special edge case. V8 will then revert to less optimal code for the specific case but this code is more general and can handle the special case that occurred.

V8 can and will toggle between optimized and unoptimized versions of your code now and then but it has limits. If it cannot settle on a version of your function that is optimized it will stop trying to optimize the code because the cost of doing so is significant.

When you write your JavaScript as if it was more statically typed than it actually is, you do enjoy optimization benefits from V8.

Unfortunately a big issue in TypeScript is that objects can and surprisingly often do have the completely wrong type. Some libraries even blatantly violate their TypeScript types. So any optimizations which take advantage of TypeScript types are likely to lead to very hard to debug behavior.

A better option is to make/use a language which interfaces well with JavaScript but is not JavaScript and actually checks it’s types. If the type system is actually be sound, and any code going in from JavaScript is type-checked at runtime, then compiler optimizations are reasonable.

As for your last point, I know that JIT-compilers like V8 can and do infer types at runtime (e.g. by noticing if a particular variable or function arg is always set to the same type) and will compile specialized function overloads which take advantage of the inferred type for optimizations (e.g. using fixed-width integers even though all JavaScript numbers are doubles).