HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

Random weighted 'tick' function

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
randomweightedfunctiontick

Problem

This is a very simple function, but it gets run on a roughly 10ms interval, so I'm looking for ways to improve it. The first obvious thing is that it has to run the comparisons nearly every time as it starts with the lowest probabilities first. Is there a way I can reverse that without breaking it, or a way I can generally improve the performance of this function to achieve the same end result?

function find_coin() {
    var roll = Math.random() * 100;

    if (roll < 0.01)
        currency['platinum']++;
    else if (roll < 0.1)
        currency['gold']++;
    else if (roll < 1)
        currency['silver']++;
    else if (roll < 10)
        currency['bronze']++;
};

Solution

Reversing the order of the tests is probably your best option here. In your current code:

function find_coin() {
    var roll = Math.random() * 100;

    if (roll < 0.01)
        currency['platinum']++;
    else if (roll < 0.1)
        currency['gold']++;
    else if (roll < 1)
        currency['silver']++;
    else if (roll < 10)
        currency['bronze']++;
};


90% of your random values will be >= 10, additionally, 9 % will be between 1 and 10 %, so, 99% of your tests will have to check.... 4 roll conditions (< 0.01, < 0.1, < 1, and < 10). So, 99% of all your rolls will check 100% of your conditions.

If you reverse the logic, and do:

function find_coin() {
    var roll = Math.random() * 100;

    if (roll >= 10) {
        return
    }

    if (roll >= 1) { 
        currency['bronze']++;
    } else if (roll >= 0.1) {
        currency['silver']++;
    } else if (roll >= 0.01) {
        currency['gold']++;
    } else {
        currency['platinum']++;
    }

};


With the above code, 90% of your rolls will do just one test, 9% will do 2 tests, 0.9 will do 3 tests, and so on.

Note, also, that I have used braces even for the 1-liner blocks in the conditions. This is a good practice and it avoids bugs when maintaining your code, later.

Code Snippets

function find_coin() {
    var roll = Math.random() * 100;

    if (roll < 0.01)
        currency['platinum']++;
    else if (roll < 0.1)
        currency['gold']++;
    else if (roll < 1)
        currency['silver']++;
    else if (roll < 10)
        currency['bronze']++;
};
function find_coin() {
    var roll = Math.random() * 100;

    if (roll >= 10) {
        return
    }

    if (roll >= 1) { 
        currency['bronze']++;
    } else if (roll >= 0.1) {
        currency['silver']++;
    } else if (roll >= 0.01) {
        currency['gold']++;
    } else {
        currency['platinum']++;
    }

};

Context

StackExchange Code Review Q#58285, answer score: 10

Revisions (0)

No revisions yet.