JSFiddle - React, Tailwind, and code Playground
HTML
<body>
<div><a href="#" id="click">Detect Concurrency</a></div>
<div id="max"></div>
</body>
JavaScript
// create worker concurrency estimation code as blob
var blobUrl = URL.createObjectURL(new Blob(['(',
function() {
self.addEventListener('message', function(e) {
// run worker for 4 ms
var st = Date.now();
var et = st + 4;
while(Date.now() < et);
self.postMessage({st: st, et: et});
});
}.toString(),
')()'], {type: 'application/javascript'}));
document.getElementById('click').addEventListener('click', function() {
document.getElementById('max').innerHTML = 'Testing concurrency...';
// take 10 samples using 16 workers
sample([], 10, 16, function(err, cores) {
document.getElementById('max').innerHTML = 'Max concurrency: ~' + cores + ' cores';
});
});
function sample(max, samples, numWorkers, callback) {
if(samples === 0) {
// get overlap average
var avg = Math.floor(max.reduce(function(avg, x) {
return avg + x;
}, 0) / max.length);
avg = Math.max(1, avg);
return callback(null, avg);
}
map(numWorkers, function(err, results) {
max.push(reduce(numWorkers, results));
sample(max, samples - 1, numWorkers, callback);
});
}
function map(numWorkers, callback) {
var workers = [];
var results = [];
for(var i = 0; i < numWorkers; ++i) {
var worker = new Worker(blobUrl);
worker.addEventListener('message', function(e) {
results.push(e.data);
if(results.length === numWorkers) {
for(var i = 0; i < numWorkers; ++i) {
workers[i].terminate();
}
callback(null, results);
}
});
workers.push(worker);
}
for(var i = 0; i < numWorkers; ++i) {
workers[i].postMessage(i);
}
}
function reduce(numWorkers, results) {
// find overlapping time windows
var overlaps = [];
for(var n = 0; n < numWorkers; ++n) {
var r1 = results[n];
var overlap = overlaps[n] = [];
for(var i = 0; i < numWorkers; ++i) {
if(n === i) {
continue;
}
var r2 = results[i];
if((r1.st > r2.st &&...