Live data from Hacker News

Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

rust-lang.org

291–300 of 307 posts

Re: Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

#291
post #101

Earlier quoted context omitted.

How much is that actually necessary these days? I remember spending ages tweaking flags in the 1.4 - 1.6 years. But there have increasingly been sensible defaults with broad applicability. Now that G1 is both default and usable, even more so. As i've moved onto 11, i've slashed our apps' JAVA_OPTS down to almost nothing - max heap size, some GC logging flags, that's it.

At scale? Very necessary. The default GC as of Java 8 (the last version I used in production) suffered significant performance issues above 40 GB of working set, and required careful tuning thereafter.

The default GC as of OpenJDK 8.

The default GC from IBM, Azul, and others wasn't the same one.

In fact Azul has made a business of selling JVMs with GC that can handle hundreds of data GBs.

Modern OpenJDK versions also have such GCs now.

Re: Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

#292

> Java was excluded from consideration because of the requirement of deploying the JVM and associated libraries along with any program to their production servers. This was an amount of operational complexity and resource overhead that was as undesirable as the unsafety of C or C++. Just so everyone here is aware, this is by now an outdated complaint against Java. https://vertx.io/blog/eclipse-vert-x-goes-native/ I'm…

Are there any companies using these native images in production?

Twitter uses GraalVM in production, you can find several talks from them.

Beyond that, enterprises using PTC, Aicas, IBM, ExcelsiorJET JDKs have had the option to deploy AOT native code in production for the last 20 years or so.

Re: Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

#293
The statement about Go using global dependencies being the standard is just someone’s opinion on the Go team. I’ve written Go for a few years now and never once shared a dep across projects. Create a new folder, set your GOPATH (use direnv) and pull your deps. I very much doubt they’ll be more productive in rust vs Go had they actually given Go a chance.

Re: Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

#294
post #196

> Java was excluded from consideration because of the requirement of deploying the JVM and associated libraries along with any program to their production servers. This was an amount of operational complexity and resource overhead that was as undesirable as the unsafety of C or C++. Just so everyone here is aware, this is by now an outdated complaint against Java. https://vertx.io/blog/eclipse-vert-x-goes-native/ I'm…

This is not at all outdated. GraalVM and SubstrateVM are still very new and only support a subset of JVM features. The Vert.x article itself mentions that, as well as this: https://github.com/oracle/graal/blob/master/substratevm/LIMI...

Before I respond, please don't misinterpret me. I think it is perfectly acceptable to choose Rust over Java saying nothing more than, "We felt Rust would be a better fit for the team," or "We were more excited by Rust." However, if somehow you have imposed on you the constraint that you need to compile ahead of time, this is not enough to toss Java out of the running.

Vert.x encountered some issues with reflection while Rust simply does not support the sort of dynamic reflection that Java running on the JVM can achieve. SubstrateVM forces you to have compile time reflection, and Rust can also support this to some extent. If Rust is a feasible alternative to Java for you, then you are not going to encounter this limitation if you choose to go with Java. Plus, if you ever decide you do need this power in your application, if you go with Java you can pay the cost of the increased operational expense and install a JVM.

Re: Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

#295

Earlier quoted context omitted.

Lots of users. Anything will be CPU-heavy if you give it enough work. Except the things that end up being memory-bound instead, but the NPM database isn't large enough for that.

Couldn't you implement the authorization logic in, say, Redis? Then the npm service is I/O-bound again, and everyone is doing the job they're optimized for.

Authorization checks aren't that expensive. The overhead of using an external service might well make it take up more hardware overall.

Re: Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

#296

Earlier quoted context omitted.

You can have options and have good default values for those options. Good default values are those that are reasonable for most people most of the time such that they don't need to be (or hire) domain experts to properly configure their tool. My opinion of a bad default would include a language toolchain which defaults to dynamic linking and requires one to opt into static linking (Java, Python, JS, etc, etc, etc). W…

So the JVM run-time is installed and used by average people, so the defaults should be set for this people that install Java to run a desktop app IMO, the developers that want extra performance should read the manual and configure things.

I’ve never heard of a runtime that forces a dichotomy between end-user- and developer-friendliness (putting aside for the moment that end users are famously annoyed by the Java runtime). Rust, Go, etc don’t have runtimes which force a choice between end-users and developers...

Re: Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

#297

Earlier quoted context omitted.

The distinction in the vernacular between statically typed and strongly typed languages is so narrow at this point that pointing it out is a bit pedantic. I would say Rust is both a strongly typed language and a statically typed language. The static type checking happens at compile time, and in general the types in use are strict and strongly typed at runtime. But, even Rust allows you to cast types from one to anoth…

It wasn't intended as a drive-by pedantic swipe - I was genuinely curious whether OP meant strong or static. Conversations about type systems and application correctness are exactly the place where precise definitions are welcomed, but I understand that the distinction between strong and static is often conflated. It can be relevant if we're discussing static typing for example, as then something like TypeScript beco…

I think I meant static and typed strong.

Re: Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

#298
post #152

Earlier quoted context omitted.

The k8s team probably should, judging from the state of their codebase.

Easy to criticize a projects that has x millions line of codes. Every projects of that scale are going to have issues.

There's a lot of circumstantial evidence suggesting that efforts to refactor the codebase were torpedoed because of developer elitism.

Re: Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

#299

Earlier quoted context omitted.

The k8s team probably should, judging from the state of their codebase.

I’m interested to see what becomes of https://www.cloudatomiclab.com/rustyk8s/

I'd kill for a rust client with feature parity. Writing k8s operators in rust would be so much better.

Re: Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]

#300

Earlier quoted context omitted.

Do you mean static typing?

The distinction in the vernacular between statically typed and strongly typed languages is so narrow at this point that pointing it out is a bit pedantic. I would say Rust is both a strongly typed language and a statically typed language. The static type checking happens at compile time, and in general the types in use are strict and strongly typed at runtime. But, even Rust allows you to cast types from one to anoth…

> The distinction in the vernacular between statically typed and strongly typed languages is so narrow at this point that pointing it out is a bit pedantic.

I'm not sure why you think this has changed today, or what you mean. It appears to me that many programmers don't realize that the two are orthogonal, so I find it an important, not pedantic, distinction (it just happens that languages generally improve on both fronts over time, hence asking for one also gives you the other, but it's because of correlation, not causation). I'll make an attempt at describing it here, please tell if I'm missing something.

Strong typing means that types describe data in a way that the data won't accidentally be mistreated as something else than what it represents. E.g.

(a) take bytes representing data of one type and interpret it as data of another type (weak: C; strong: most other languages)

(b) take a string and interpret it as a number without explicitly requesting it (weak: shells, Perl; strong: Python, JavaScript, Ruby)

(c) structs / objects / other kinds of buckets, (strong: C if type wasn't casted; weak: using arrays or hash map without also using a separate type on them that is enforced, the norm in many scripting languages although usually strengthened via using accessor methods which are automatically dispatched via some kind of type tag; also, duck typing is weaker than explicit interfaces)

(d) describe data not just as bare strings or numbers, but wrap (or tag / typedef etc.) those in a type that describes what it represents (this depends on the programmer, not the language)

(e) a request of an element that is not part of an array / list / map etc. is treated as an error (similar to or same as a type error (e.g. length can be treated as being part of the type)) instead of returning wrong data (unrelated memory, or a null value which can be conflated with valid value)

These type (or data) checks can happen at runtime ("dynamically") or compiletime ("statically"). The better a static type system is, the more of these checks can be done at compile time.

For security and correctness, having strong typing is enough in principle: enforcing type checks at runtime just means getting a failure (denial of service), and systems should be designed not to become insecure or incorrect when such failures happen (fail closed), which of course might be done incorrectly [1]. Testing can make the potential for such failures obvious early (especially randomized tests in the style of quickcheck).

Static typing makes the potential for such failures obvious at compile time. It's thus a feature that ensures freedom of denial of service even in the absense of exhaustive testing. It can also be a productivity feature (static inspection/changes via IDE), and it can enable more extensive use of typing as there is no cost at run time.

[1] note that given that static typesystems usually still allow out of memory failures at run time, there's usually really no way around designing systems to fail closed anyway.

Post reply on HN