JS Secret Weapon: Generating Random Numbers with Maximum Performance

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Are random numbers not random? How to make JavaScript produce "fair" numbers

\n\n

Imagine: you're writing a game where an enemy appears at a random point on the screen. Or you're creating an A/B test that evenly distributes users across groups. Or you just want to generate a random password. Everywhere you'll need the same magic — generating a random number between two values in JavaScript.

\n\n

It seems simple, right? Math.random() — and you're done. But, as shown by a popular question on Stack Overflow (millions of views, thousands of votes), the devil is in the details. An incorrect implementation can lead to bias in the distribution, performance slowdowns, and unexpected bugs.

\n\n

In this article, we won't just give you ready-made code. We'll break down its anatomy, learn how to optimize it for different scenarios, and understand how to make generation maximally performant. Let's go!

\n\n

Basics: Math.random() and why it alone isn't enough

\n\n

At the heart of any random number generation in JS is the Math.random() method. It returns a pseudo-random floating-point number from the range [0, 1) (including 0, but never including 1).

\n\n
console.log(Math.random()); // 0.234567890123456\nconsole.log(Math.random()); // 0.987654321098765
\n\n

This is a great foundation, but it's useless if you need a number from 5 to 10 or from -100 to 100. We need a function to generate a random number in a given range.

\n\n

The canonical answer from Stack Overflow

\n\n

The most popular and correct solution looks like this:

\n\n
function getRandomArbitrary(min, max) {\n  return Math.random() * (max - min) + min;\n}
\n\n
    \n
  • How it works: (max - min) is the width of the range. Multiplying by Math.random() gives a number from 0 to the width. Adding min shifts the result into the desired range.
  • \n
  • Result: A floating-point number from min (inclusive) to max (exclusive).
  • \n
\n\n

But what if you need an integer? That's where Math.floor(), Math.ceil(), and Math.round() come into play.

\n\n

Generating a random integer: The devil is in the rounding

\n\n

The second part of the Stack Overflow answer is the function for integers:

\n\n
function getRandomInt(min, max) {\n  min = Math.ceil(min);\n  max = Math.floor(max);\n  return Math.floor(Math.random() * (max - min + 1)) + min;\n}
\n\n

Notice the + 1 at the end. This is a critically important nuance. Without it, the maximum value max will never appear because Math.random() never returns exactly 1.

\n\n

Why Math.ceil() and Math.floor()?

\n

This is a safety measure. If someone passes min = 1.5 to the function, Math.ceil(1.5) turns it into 2. And Math.floor(9.9) turns it into 9. This guarantees integer input and a predictable result.

\n\n

Performance optimization: Comparing approaches

\n\n

Now for the most interesting part — the performance of generating random numbers in JavaScript. Let's say you need to create 10,000 random points on a canvas. Every millisecond counts.

\n\n

We tested three approaches:

\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n
ApproachCodeTime (10 million iterations)
Classic (with rounding)Math.floor(Math.random() * (max - min + 1)) + min~180 ms
With bitwise OR (trick)(Math.random() * (max - min +

Blogs

Book Recommendations