Oleg A.’s Post

I compared the same logic in JS and Rust. The result? The "complex" Rust version wasn't just drastically faster — it was actually shorter and cleaner. If you’ve worked with JavaScript, Python, or Java, you’ve likely encountered the classic problem of counting how many times each character appears in a string. In JavaScript, the typical approach looks like this: if (map.has(ch)) { map.set(ch, map.get(ch) + 1); } else { map.set(ch, 1); } While this seems straightforward, there’s a hidden performance flaw: The Double Lookup & Value Copying. This one-liner requires extra work from the engine: 1️⃣ map.get(ch): Calculates the hash, traverses memory, finds the bucket, and extracts a copy of the number. 2️⃣ + 1: Creates a brand-new number primitive in memory. 3️⃣ map.set(ch, ...): Calculates the hash again, traverses memory again, finds the same bucket, and copies the new number back into it. Now, let's see how Rust handles the same logic: *counts.entry(ch).or_insert(0) += 1; This isn't just syntactic sugar; it utilizes Rust's Entry API, designed for maximum hardware efficiency. Here’s why it’s blazingly fast: - It calculates the hash exactly once. - It locates the memory bucket exactly once. - It returns a &mut (a direct mutable pointer/reference) right to that memory slot. The += operator modifies the primitive value in-place without copying it out or needing a .set() method to put it back. This results in code that reads like a high-level script but executes with the speed of a systems language. Zero-cost abstractions at their finest! #Rust #JavaScript #Programming #Performance #SoftwareEngineering #WebDev #RustLang

  • graphical user interface, text, application

I think in this case Rust is doing double insertion in case it does not exist, but to keep things leveled, here’s an optimized JS version: `map.set(ch, map. getOrInsert(ch, 0) + 1)` Although it might look like hash is calculated twice, V8 (and possibly other engines) cache it if it’s a string, numbers are just the hash themselves and general objects use an internal ID that is computed only once and stored in the object itself.

Rust might be fast and "clean" and fancy, but I can put into same JS Map keys of any primitive type, and literally any value. In practice it means I can caching "class" is ok for any data I can possibly receive from DB or MQ. And it is fast enough not to be bottleneck.

Is this comparison really important? May be I'm wrong. One is JIT compiled and the other is AOT complied. And the use cases differ.

Like
Reply

Putting js in the backend has always been the single biggest mistake the industry ever made 🤦🏻

You can write your own helper

Like
Reply

Is Rust's version thread-safe? Java has `compute` methods for its Map interface which, depending on the implementation, will acquire a lock and perform the update atomically

javascript: const v = map.get(ch) ?? 0 map.set(ch, ch+1)

Reminds me of c++ where map.[] returns a mutable reference to either the existing value or freshly inserted one

Like
Reply
Adam Baranyai

Senior NodeJs Full-Stack Software Engineer • Typescript Enthusiast | Designing and building scalable software systems.

4w

const num = (map.get(ch) ?? 0); map.set(num + 1);

See more comments

To view or add a comment, sign in

Explore content categories