Как оптимизировать скорость вычислений в array.forEach в node.js - PullRequest
0 голосов
/ 30 августа 2018

У меня есть фрагмент кода, который просто перебирает два массива и для каждого элемента первого массива находит соответствующий элемент во втором массиве, изменяет только первое вхождение и удаляет остальные.

 /**
     * The aggregation data structure:
     * "_id": {
     * "geometry": geometry,
     * "dups": [
     *    "5b3b25b4e54029249c459bfc", keep only the fisrt element in allDocs
     *    "5b3b25b4e54029249c459e65", delete it from allDocs
     *    "5b3b25b4e54029249c459d7d"   delete it from allDocs
     *   ],
     * "dupsProp": [  ], array of all properties of duplicatePoints
     * "count": 3
     */
var aggregationRes =[46,000 objects]
var allDocs =[345,000 objects]
aggregationRes.forEach(function (resElem, counter) {
        console.log(counter + "/" + aggregationRes.length)
        //Delete objects in allDocs based on dups array except the first one
        var foundIndex = allDocs.findIndex(x => x._id.toString() == resElem.dups[0]);
                //assign the mergedProperties
        allDocs[foundIndex].properties = resElem.dupsProp;
        //delete the remaining ids in Docs from dups array 
        resElem.dups.forEach(function (dupElem, index) {
            var tmpFoundIndex = allDocs.findIndex(x => x._id.toString() == resElem.dups[index + 1]);
            if (tmpFoundIndex !== -1) {
                allDocs.splice(tmpFoundIndex, 1)
            }
        })
    })

Этот скрипт выполняется почти 4 часа. Как видите, вычисления очень просты, но поскольку массив allDocs большой, он занимает довольно много времени. Было бы здорово, если бы кто-нибудь дал мне подсказку о том, как сократить время вычислений. Заранее спасибо

1 Ответ

0 голосов
/ 31 августа 2018

Беря идеи Берги, мы индексируем документы по id, чтобы избежать необходимости находить дорогие индексы:

var allDocs =[345,000 objects]
var aggregationRes =[46,000 objects]
var allDocsIndexed = {};

allDocs.forEach(function(doc){
    allDocsIndexed[doc._id.toString()] = doc;
});

aggregationRes.forEach(function (resElem, counter) {
    allDocsIndexed[resElem.dups[0]].properties = resElem.dupsProp;
    for (var i = 1; i < resElem.dupsProp.length; i++) {
        delete allDocsIndexed[resElem.dupsProp[i]];
    }
});

var allUndeletedDocs = allDocs.filter(doc => allDocsIndexed.hasOwnProperty(doc_id.toString()));

Обратите внимание, что для javascript это эффективное решение, но с более подробной информацией может быть лучше, используя функции mongodb.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...