Live data from Hacker News

A 10x Faster TypeScript

devblogs.microsoft.com

671–680 of 943 posts

Re: A 10x Faster TypeScript

#671

Earlier quoted context omitted.

> First, they are using WASM which itself is a a low-level representation. WASM is used to generate the query plan, but query execution now happens entirely within TypeScript, whereas under the previous architecture both steps were handled by Rust. So in a very literal sense some of the Rust code is being rewritten in TypeScript. > Basically, if the majority of your application is already in JavaScript and expects pr…

I'm not denying the facts of the matter, I am denying the conclusion. The circumstances of the situation are relevant. Marshalling cost across IPC boundaries come into play in every single possible situation regardless of language. It is why shared memory architectures exist. It doesn't matter what language is on the other side of the IPC, if the performance gained by using a separate process is not greater than the…

Rather than fixating on this single Prisma example, I'd like to address your larger point which seems to be that all greenfield projects are necessarily best suited to low level languages.

First of all, I would argue that software rewrites are a bad proxy metric for language quality in general. Language rewrites don't measure languages purely on a qualitative scale, but rather on a scale of how likely they are to be misused in the wrong problem domain.

Low level languages tend to have a higher barrier to entry, which as a result means they're less likely to be chosen on a whim during the first iteration of a project. This phenomenon is exhibited not just at the macroscopic level of language choice, but often times when determining which data structures and techniques to use within a specific language. I've very seldomly found myself accidentally reaching for a Uint8Array or a WeakRef in JS when a normal array or reference would suffice, and then having to rewrite my code, not because those solutions are superior, but because they're so much less ergonomic that I'm only likely to use them when I'm relatively certain they're required.

This results in obvious selection bias. If you were to survey JS developers and ask how often they've rewritten a normal reference in favor of a WeakRef vs the opposite migration, the results would be skewed because the cost of dereferencing WeakRefs is high enough that you're unlikely to use them hastily. The same is true to a certain extent in regards to language choice. Developers are less likely to spend time appeasing Rust's borrow checker when PHP/Ruby/JS would suffice, so if a scripting language is the best choice for the problem at hand, they're less likely to get it wrong during the first iteration and have to suffer through a massive rewrite (and then post about it on HN). I've seen plenty of examples of competent software developers saying they'd choose a scripting language in lieu of Go/Rust/Zig. Here's the founder of Hashicorp (who built his company on Go, and who's currently building a terminal in Zig), saying he'd choose PHP or Rails for a web server in 2025: https://www.youtube.com/watch?v=YQnz7L6x068&t=1821s

Re: A 10x Faster TypeScript

#672
post #653

Earlier quoted context omitted.

Because running a parallel process is often difficult. In most cases, the question becomes: So, how exactly is my app/whatever supposed to spin up a parallel process in the OS and then talk to it over IPC? How do you shut it down when the 'host' process dies? Not vaguely. Not hand wave "just launch it". How exactly do you do it? How do you do it in environments where that capability (spawning arbitrary processes) is…

> So, how exactly is my app/whatever supposed to spin up a parallel process in the OS and then talk to it over IPC? Usually the very easiest way to do this is to launch the target as a subprocess and communicate over stdin/stdout. (Obviously, you can also negotiate things like shared memory buffers once you have a communication channel, but stdin/stdout is enough for a lot of stuff.) > How do you shut it down when th…

Thanks for chiming in with these details, but I would just like to say:

> It will not conflict with other applications that do the same thing.

It is possible not to conflict with existing parallel deployments, but depending on your IPC mechanism, it is by no means assured when you're not forking and are instead launching an external process.

For example, it could by default bind a specific default port. This would work in the 'naive' situation where the client doesn't specify a port and no parallel instances are running. ...but if two instances are running, they'll both try to use the same port. Arbitrary applications can connect to the same port. Maybe you want to share a single compiler service instance between client apps in some cases?

Not conflicting is not a property of parallel binary deployment and communication via IPC by default.

IPC is, by definition intended to be accessible by other processes.

Jupyter kernels for example are launched with a specified port and a secret by cli argument if I recall correctly.

However, you'd have to rely on that mechanism being built into the typescript compiler service.

...ie. it's a bit complicated right?

Worth it for the speedup? I mean, sure. Obviously there is a reason people don't embed postgres. ...but they don't try to ship a copy of it along side their apps either (usually).

Re: A 10x Faster TypeScript

#673
post #607
post #599

Earlier quoted context omitted.

.NET has been able to build a self contained single file executable for both the JIT and AOT target for a quite some time. Java also does not require the user to install a runtime. JLink and JPackage have both been around for a long time.

Maybe some other runtimes do this or it has been changed, but in the past self-contained singe-file .NET deployment just meant that it rolled all the files up during publishing and when you run it, it extracted them to a folder. Not really like a single statically linked executable.

You can indeed produce a compiled native executable with minimal bloat: https://learn.microsoft.com/en-us/dotnet/core/deploying/nati...

Re: A 10x Faster TypeScript

#674

Earlier quoted context omitted.

>Pity that they didn't go with AOT compiled .NET, though. I was trying ot push .net as our possible language for somehow high performance executables. Seeing this means I'll stop trying to advocate for it. If even this team doesn't believe in it.

They cited code style and porting as reasons to use go over c#, not performance.

Also cross platform support

Re: A 10x Faster TypeScript

#675
post #472

Earlier quoted context omitted.

For anyone who uses TypeScript on a daily basis it's not ambiguous at all. Everyone who works with TS knows the runtime code is JavaScript code that is generated by the TypeScript compiler. And it's also pretty common knowledge that JavaScript is quite fast, but TS itself is not.

And if this post was about a TS compiler that emitted x86 executables you would be wrong and find out that it is indeed ambiguous.

Why would a hypothetical "tsx86" project write an article titled "10x faster typescript" instead of "10x faster binaries with tsx86 2.0"

If you have to invent things for something to be considered ambiguous, is it really ambiguous?

Re: A 10x Faster TypeScript

#676
Not sure if this point was brought up but I think it's worth considering.

If the Typescript team were to go with Rust or C# they would have to contend with async/await decoration and worry about starvation and monopolization.

Go frees the developer from worrying about these concerns.

Re: A 10x Faster TypeScript

#677
post #660
post #646

Earlier quoted context omitted.

I highly doubt that bolting a GC on to C++ is going to be any faster than the equivalent C# or Java code.

Doubt is human, but it isn’t always warranted. In C++ can use a concurrent, completely pause‐free garbage collector, where the programmer decides which data is managed by the GC. This enables code optimizations in ways that aren’t possible in C# and Java.

You realize that is literally not the same thing? I said equivalent code. The whole reason of using a managed language with GC is to not think about those things because they eat up thought and development time. Of course the language that will let you hand optimize every little line will eventually be more performant. I really think you’re discounting both C#’s ability to do those things and just how good Java’s GCs are. Anyway, thats not the point.

The point is C++ sucks dude. There is no way that you can reasonably think that bolting a GC on to C++ is going to be a pleasurable experience. This whole conversation started with _language ergonomics_. I don’t care that it’ll save 0.5 milliseconds. I’d rather dig holes than write C++.

Re: A 10x Faster TypeScript

#678
post #653

Earlier quoted context omitted.

> So, how exactly is my app/whatever supposed to spin up a parallel process in the OS and then talk to it over IPC? Usually the very easiest way to do this is to launch the target as a subprocess and communicate over stdin/stdout. (Obviously, you can also negotiate things like shared memory buffers once you have a communication channel, but stdin/stdout is enough for a lot of stuff.) > How do you shut it down when th…

Thanks for chiming in with these details, but I would just like to say: > It will not conflict with other applications that do the same thing. It is possible not to conflict with existing parallel deployments, but depending on your IPC mechanism, it is by no means assured when you're not forking and are instead launching an external process. For example, it could by default bind a specific default port. This would wo…

> Not conflicting is not a property of parallel binary deployment

I fail to see how starting another process under an OS like Linux or Windows can be conflicting. Don't share resources, and you're conflict-free.

> IPC is, by definition intended to be accessible by other processes

Yes, but you can limit the visibility of the IPC channel to a specific process, in the form of stdin/stdout pipe between processes, which is not shared by any other processes. This is enough of a channel to coordinate creation of a more efficient channel, e.g. a shmem region for high-bandwidth communication, or a Unix domain socket (under Linux, you can open a UDS completely outside of the filesystem tree), etc.

A Unix shell is a thing that spawns and communicates with running processes all day long, and I'm yet to hear about any conflicts arising from its normal use.

Re: A 10x Faster TypeScript

#679

Earlier quoted context omitted.

They are still going to significant bigger than the equivalent golang binary because of the huge .NET runtime, no?

https://github.com/MichalStrehovsky/sizegame C#: 945 kB Go: 2174 kB

Since this is just Hello World, then TinyGo: 644kB

Re: A 10x Faster TypeScript

#680

Hi folks, Daniel Rosenwasser from the TypeScript team here. We're obviously very excited to announce this! RyanCavanaugh (our dev lead) and I are around to answer any quick questions you might have. You can also tune in to the Discord AMA mentioned in the blog this upcoming Thursday.

Like others I'm curious about the choice of technology here. I see you went with Go, which is great! I know Go is fast! But its also a more 'primitive' language (for lack of a better way of putting it) with no frills. Why not something like Rust? Most of the JS ecosystem that is moving toward faster tools seem to be going straight to Rust (Rolldown, rspack (the webpack successor) SWC, OXC, Lightning CSS / Parcel etc)…

| with no frills.

People say this like it's a bad thing. It's not, it's Go's primary strength.

Post reply on HN