Недавно я пытался использовать интерфейс Web Workers для экспериментов с потоками в JavaScript.
Попытка создать contains с помощью веб-воркеров, выполнив следующие действия:
- Разбить исходный массив на части одинакового размера
- Создайте веб-воркер для каждой части, которая запускает .contains на этой части.
- Когда и если значение найдено в любой из частей, он возвращает true, не дожидаясь завершения всех рабочих процессов.
Вот что я пробовал:
var MAX_VALUE = 100000000;
var integerArray = Array.from({length: 40000000}, () => Math.floor(Math.random() * MAX_VALUE));
var t0 = performance.now();
console.log(integerArray.includes(1));
var t1 = performance.now();
console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.");
var promises = [];
var chunks = [];
while(integerArray.length) {
chunks.push(integerArray.splice(0,10000000));
}
t0 = performance.now();
chunks.forEach(function(element) {
promises.push(createWorker(element));
});
function createWorker(arrayChunk) {
return new Promise(function(resolve) {
var v = new Worker(getScriptPath(function(){
self.addEventListener('message', function(e) {
var value = e.data.includes(1);
self.postMessage(value);
}, false);
}));
v.postMessage(arrayChunk);
v.onmessage = function(event){
resolve(event.data);
};
});
}
firstTrue(promises).then(function(data) {
// `data` has the results, compute the final solution
var t1 = performance.now();
console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.");
});
function firstTrue(promises) {
const newPromises = promises.map(p => new Promise(
(resolve, reject) => p.then(v => v && resolve(true), reject)
));
newPromises.push(Promise.all(promises).then(() => false));
return Promise.race(newPromises);
}
//As a worker normally take another JavaScript file to execute we convert the function in an URL: http://stackoverflow.com/a/16799132/2576706
function getScriptPath(foo){ return window.URL.createObjectURL(new Blob([foo.toString().match(/^\s*function\s*\(\s*\)\s*\{(([\s\S](?!\}$))*[\s\S])/)[1]],{type:'text/javascript'})); }
Любой браузер и процессор пробовали, это очень медленно по сравнению с простым contains для исходного массива.
Почему это так медленно? Что не так с кодом выше?
использованная литература
- Ожидание завершения работы нескольких рабочих операций
- Дождитесь первого истинного результата, возвращаемого обещаниями
Изменить: проблема не в .contains() конкретно, а в других функциях массива, например. .indexOf(), .map(), forEach() и т. д. Почему разделение работы между веб-воркерами занимает гораздо больше времени...
includes
. - person Pytth   schedule 21.12.2018