1

In JavaScript, is there a way to do this in a more efficient way?

I need to create an array of boolean values, change them and check them individually and at random.

The goal is better performance. Maybe manipulating bits.

Right now I use something like this:

var boolean = [];

var length = 100; // set a random number of values
for (var i = 0; i < length; i++) boolean[i] = false; // or true

boolean[n] = true; // change some of the values randomly
if (boolean[n]) { /* something */ } // check some of the values randomly
2
  • 1
    Better performance of which part? Creating the array? Filling it with false? Updating it later? Commented Oct 16, 2014 at 7:47
  • Sorry, too accustomed to notifications. The checking of the values is most important to me. Commented Oct 16, 2014 at 11:56

2 Answers 2

6

So there are three parts to this:

  1. Creating the array

    Somewhat counter-intuitively, what you're doing is already just fine even though standard JavaScript arrays aren't really arrays at all, because the way you're creating and filling in the array, a modern engine will use a true array behind the scenes. (See my answer to this other question for more on that, including performance tests.) So even on engines that have true arrays like Uint8Array, what you're doing is fine. But see point #2 below.

  2. Filling it with falsey values

    As there are only 100 entries, it just doesn't matter how you do this, unless you're creating and filling in the array repeatedly in a tight loop. If you are, then a Uint8Array should win, because new Uint8Array(100) is pre-filled with zeroes and you don't have to fill it in at all.

  3. Accessing the array's entries

    You don't really have much choice there, you do it the way you're doing it. Provided you create the array the way you are or you use a Uint8Array, that's probably as fast as it's going to get.

I find http://jsperf.com helpful for comparing approaches to things and seeing how they turn out on real-world JavaScript engines. For instance, here's a test case suggesting that a Uint8Array will offer a slight advantage on SpiderMonkey (Firefox's engine), be about the same on V8 (Chrome's engine), and very slightly slower on JScript (IE11's engine):

Standard array:

var a, n, dead;

// Creation
a = [];

// Filling
for (n = 0; n < 100; ++n) {
    a[n] = false;
}

// Accessing randomly 5,000 times
dead = 1;
for (n = 0; n < 5000; ++n) {
    a[Math.floor(Math.random() * a.length)] = true;
    if (a[Math.floor(Math.random() * a.length)]) {
        ++dead; // Just to be doing something
    }
}

// Make sure engine knows we're using the result
if (dead === 0) { throw "Error in test"; }

Uint8Array:

var a, n, dead;

// Creation
a = new Uint8Array(100);

// Filling
// None!

// Accessing randomly 5,000 times
dead = 1;
for (n = 0; n < 5000; ++n) {
    a[Math.floor(Math.random() * a.length)] = 1;
    if (a[Math.floor(Math.random() * a.length)]) {
        ++dead; // Just to be doing something
    }
}

// Make sure engine knows we're using the result
if (dead === 0) { throw "Error in test"; }

Results on Chrome, Firefox, and IE11:

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

Wow, this is a pretty cool explanation, I didn't know, that you have access to something as low-level as an actual array in js.
Thanks. Not as much of an improvement as I hoped. I guess standard arrays are pretty optimized.
@CarlosGil: Only if you play nice with them. :-) Otherwise, with some engines, you fall back into dictionary mode where array indexes are nothing more than property names (see the answer linked above for ways that can happen).
1

may be this way

var length = 100,
    item,
    arr = (Array(length)).fill(1),
    getRandBool = function() { return Math.random(Date()) * 10 > 6; },
    getRandIdx = function() { return (Math.random(Date()) * (length + 1))|0; };

arr.forEach(function(val, idx) { arr[idx]= getRandBool(); });

arr[getRandIdx()] = getRandBool();


if(item = arr[getRandIdx()]) { console.log(item) }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.