Live data from Hacker News

PR that converts the TypeScript repo from namespaces to modules

github.com

31–40 of 204 posts

Re: PR that converts the TypeScript repo from namespaces to modules

#31
post #8

Sucrase is proof that JS is not the problem when it comes to slow performance. JS is not slow. NodeJS is not slow. It's the code that is slow. All these people wanting to write it in Rust or Go or XYZ programming language need to acknowledge this. Yes, multithreading is awesome and really helpful but it's the cherry on top, not the whole thing. If the same amount of effort was put into optimizing the TSC codebase as…

How far can you get with JS/other interpreted things in e.g. optimizing for cache access etc? Sounds like you're at the mercy of the JIT compiler (which may go far, but still).

The interesting question to ask is whether these Rust rewrites are really taking advantage of cache optimization or if they are making simplifying assumptions that the canonical implementation cannot. In the latter case, Rust isn't the root of the performance difference and a JS rewrite can make most of those simplifying assumptions

Re: PR that converts the TypeScript repo from namespaces to modules

#32
post #18

Earlier quoted context omitted.

Sucrase is written in JS and boasts the highest line throughput of any competing transpiler https://github.com/alangpierce/sucrase Time Speed Sucrase 0.57 seconds 636975 lines per second swc 1.19 seconds 304526 lines per second esbuild 1.45 seconds 248692 lines per second TypeScript 8.98 seconds 40240 lines per second Babel 9.18 seconds 39366 lines per second

but the benchmark is stupid: https://github.com/alangpierce/sucrase/blob/main/benchmark/b... > Like all JavaScript code run in V8, Sucrase runs more slowly at first, then gets faster as the just-in-time compiler applies more optimizations. From a rough measurement, Sucrase is about 2x faster after running for 3 seconds than after running for 1 second. swc (written in Rust) and esbuild (written in Go) don't have this…

I don't see how this is a rebuttal to the claim. 636,975 is more than 2x 304,526, so assuming the quoted paragraph is correct, sucrase is still the highest-throughput transpiler even during its warm-up phase. Probably this isn't true for the first 100 milliseconds of execution during the very first warm-up stages, but if the transpile phase is that short, it's basically irrelevant anyway.

Re: PR that converts the TypeScript repo from namespaces to modules

#33
I absolutely hate how with Typescript and ES Modules, if you have a file

utils/foo.ts

you have to import it as

import Foo from "utils/foo.js"

Even though there is no .js file on disk, and you might be running ts-node or whatever that doesn't build a .js file.

Importing a file that "doesn't exist" is so counterintuitive.

In addition all code breaks because you have to change all your imports, and /index.ts or /index.js won't work either.

Re: PR that converts the TypeScript repo from namespaces to modules

#34
post #23

> Finally, as a result of both of the previous performance improvements (faster code and less of it), tsc.js is 30% faster to start and typescript.js (our public API) is 10% faster to import. As we improve performance and code size, these numbers are likely to improve. We now include these metrics in our benchmarks to track over time and in relevant PRs. > [...] > The TypeScript package now targets ES2018. Prior to 5…

I'm curious about that too. From my superficial knowledge of compilers, "modularization" itself should not make code faster, if anything slower. There'll always be some overhead of loading modules and communicating between them, not? I presume, from my own experience when building software (not compilers), that modules allow for a much easier to reason about, much better isolated (cohesion, loose coupling). And there…

For ES6 modules, the exports object is frozen (made read-only) so the JIT can make some extra assumptions and optimizations. With bundles, unless the bundler inserts `Object.freeze` around `module.exports`, they have to be treated as dynamic objects.

Re: PR that converts the TypeScript repo from namespaces to modules

#35
post #23

> Finally, as a result of both of the previous performance improvements (faster code and less of it), tsc.js is 30% faster to start and typescript.js (our public API) is 10% faster to import. As we improve performance and code size, these numbers are likely to improve. We now include these metrics in our benchmarks to track over time and in relevant PRs. > [...] > The TypeScript package now targets ES2018. Prior to 5…

I'm curious about that too. From my superficial knowledge of compilers, "modularization" itself should not make code faster, if anything slower. There'll always be some overhead of loading modules and communicating between them, not? I presume, from my own experience when building software (not compilers), that modules allow for a much easier to reason about, much better isolated (cohesion, loose coupling). And there…

There are some key things here that maybe weren't clearly stated in my writeup.

Firstly, the old codebase is TS namespaces, which compile down to IIFEs that push properties onto objects. Each file that declares that namespace is its own IIFE, and so every access to other files incurs the overhead of a property access.

With modules, tooling like esbuild, rollup, can now actually see those dependencies (now they are standard ES module imports) and optimize access to them. In this PR's case, the main boost comes from scope hoisting.

For example, in one file, we may declare the helper `isIdentifier`. In namespaces, we would write `isIdentifier` in another file, but this would at emit time turn into `ts.isIdentifier`, which is slower. Now, we import that helper, and then esbuild (or rollup) can see that exact symbol. All of the helpers get pulled to the top of the output bundle, and calls to those helpers are direct.

That's why modules gives us a boost. There's also more (modules means we can use tooling to tree shake the output, and smaller bundles are faster to load), but the hoisting is the big thing.

Re: PR that converts the TypeScript repo from namespaces to modules

#36
post #26

Earlier quoted context omitted.

I think tooling of one programming language should be written in the programming language. Otherwise the community will hardly be involved. All these rust tools may be slight faster, but typescript developers will not learn rust to improve the typescript compiler.

If you think of typescript as "tooling" that makes sense. But if you think of it as compiler, or transpiler, not so much. Python, Ruby etc "compilers" (runtimes, really) aren't written in Python or Ruby. Or rather, there are alternatives around, but they aren't the fastest nor the best. Such "tools" are built in C. As are compilers for C++, Rust or most languages really.

I understand your point. Compilers and interpreters are traditionally written in C/C++, but we don't have to do the same than before.

Re: PR that converts the TypeScript repo from namespaces to modules

#37
post #8

Sucrase is proof that JS is not the problem when it comes to slow performance. JS is not slow. NodeJS is not slow. It's the code that is slow. All these people wanting to write it in Rust or Go or XYZ programming language need to acknowledge this. Yes, multithreading is awesome and really helpful but it's the cherry on top, not the whole thing. If the same amount of effort was put into optimizing the TSC codebase as…

How far can you get with JS/other interpreted things in e.g. optimizing for cache access etc? Sounds like you're at the mercy of the JIT compiler (which may go far, but still).

With stuff like TypedArrays pretty far. Where JS has problems is optimising in the face of the things you can do with the language and the current difficulty in multithreaded implementations.

Re: PR that converts the TypeScript repo from namespaces to modules

#38
post #18

Earlier quoted context omitted.

but the benchmark is stupid: https://github.com/alangpierce/sucrase/blob/main/benchmark/b... > Like all JavaScript code run in V8, Sucrase runs more slowly at first, then gets faster as the just-in-time compiler applies more optimizations. From a rough measurement, Sucrase is about 2x faster after running for 3 seconds than after running for 1 second. swc (written in Rust) and esbuild (written in Go) don't have this…

I don't see how this is a rebuttal to the claim. 636,975 is more than 2x 304,526, so assuming the quoted paragraph is correct, sucrase is still the highest-throughput transpiler even during its warm-up phase. Probably this isn't true for the first 100 milliseconds of execution during the very first warm-up stages, but if the transpile phase is that short, it's basically irrelevant anyway.

the warm-up phase is the whole reason why esbuild and swc exists btw. and also the sample is basically a small hello world. any real project would do a little more and the jit would not optimize as much.

also 2x 300k is not really the way how multi-threading/concurrency/parallelism works... especially not golang, which should not be run with GOMAXPROCS=1....

Re: PR that converts the TypeScript repo from namespaces to modules

#39
post #33

I absolutely hate how with Typescript and ES Modules, if you have a file utils/foo.ts you have to import it as import Foo from "utils/foo.js" Even though there is no .js file on disk, and you might be running ts-node or whatever that doesn't build a .js file. Importing a file that "doesn't exist" is so counterintuitive. In addition all code breaks because you have to change all your imports, and /index.ts or /index.j…

Every TypeScript project I have worked on either:

1) enforces no extension, e.g. “utils/foo”, or

2) allows TS extensions, e.g. “utils/foo.ts”

I have never imported a TS file using a JS extension. Maybe your woes could be fixed with a configuration change?

Re: PR that converts the TypeScript repo from namespaces to modules

#40
post #8

Sucrase is proof that JS is not the problem when it comes to slow performance. JS is not slow. NodeJS is not slow. It's the code that is slow. All these people wanting to write it in Rust or Go or XYZ programming language need to acknowledge this. Yes, multithreading is awesome and really helpful but it's the cherry on top, not the whole thing. If the same amount of effort was put into optimizing the TSC codebase as…

[deleted]
Post reply on HN