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
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
Share
Improve this question
asked Oct 16, 2014 at 7:45
Carlos GilCarlos Gil
6054 gold badges12 silver badges25 bronze badges
2
-
1
Better performance of which part? Creating the array? Filling it with
false
? Updating it later? – T.J. Crowder Commented Oct 16, 2014 at 7:47 - Sorry, too accustomed to notifications. The checking of the values is most important to me. – Carlos Gil Commented Oct 16, 2014 at 11:56
2 Answers
Reset to default 6So there are three parts to this:
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.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, becausenew Uint8Array(100)
is pre-filled with zeroes and you don't have to fill it in at all.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. helpful for paring 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:
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) }