How to emulate any load profile with simple random() function in JavaScript or any other language

Alexey Himself
4 min readMay 15, 2023

--

TL;DR

When you have a list of items, for example: [a, b, c], and you want to get, for example, a linear distribution of them with usual .random() function then simply make a number of items in that list in linear distribution: [a, b, b, c, c, c] and then get .random() from this new list — and you’ll get the result in linear distribution:

You can make harder angle or softer angle by adding more or less items for each next step, for example:

  • Softer than 45*: [a, b, c, c]
  • Exactly 45*: [a, b, b, c, c, c]
  • Harder than 45*: [a, b, b, b, c, c, c, c, c, c]

And this is applied not only for linear, but for any type of profiles: normal distribution, exponent, square, etc. — every profile, every curve could be emulated with a simple .random() function.

How I came to this

I develop Product Analytics app and it has demo mode. And it has sankey (tree) chart. But when I flushed the chart with .random() data, it looked stupid, unreal and not interesting — every branch height was about the same (which means: used the same compared to each other):

I wanted to have a normal distribution for that chart to make some items narrow, another items wide — to be more interesting to look at and play with. But there’s no built-in function for normal distribution in Vanilla JavaScript. Instead — a long discussion thread on StackOverflow.

Looking at the normal distribution chart plot I eventually came to an idea, that these vertical bars represent repetition of the X values. And this means that instead of having only one value for each X in array I can have N values for each X in array and then pass .random() function among elements of that array — and I will get what I want: random, but in a form I wanted.

Image from: https://www.scribbr.com/statistics/normal-distribution

So, I made this modification — I increased number of elements:

  • original list: [a, b, c, d, e]
  • normal distribution list: [a, b, b, c, c, c, c, c, d, d, e]

And it worked:

See? How much interesting this chart compared to original .random() one!

And if we put data in a table a sort values from max to min, then we’ll see that hals of the “bell curve” of normal distribution:

A half of curve because of sorting: it brings everything on one side, making original curve as twice as wide.

That’s why when I wanted to simulate users and I wanted to make linear simulation, I made simulation the same way and got this:

And all together, the whole picture now looks like this:

  • normal distribution for sankey (tree) chart and a table below on the left side,
  • linear distribution for UserIDs in the center,
  • and constant simple .random() distribution in time on the right:

And all these are made by simple and the same, single .random() function.

Source code for JavaScript

Bonus

Only for those who read till the end!

As arrays could be complex and heavy, multiplication of their elements could cost you a lot in terms of RAM consumption. That’s why instead of multiplication of the elements themselves, multiply their IDs:

  • original: [a, b, c]
  • linear “bad practice”: [a, b, b, c, c, c]
  • linear “good practice”: [0, 1, 1, 2, 2, 2] — ID’s for a, b and c

and get .random() from IDs array and then get the original element from original array by that ID.

Hope you liked it and had fun!

--

--

Alexey Himself

I write about practical and effective techniques that help me and my colleagues in everyday software development and testing.