Улучшение повторяющегося Finder и для работы Loop

81
9

Я создал скрипт, который найдет дубликаты ключа в массиве объектов. Если дубликаты найдены, новый ключ и значение ("Дубликат": истина) добавляются к объектам с повторяющимися значениями ключа.

Пример данных

{
"Id": "1",
"NI Number": "NG111111A",
"Full Name": "Test Test Tester",
"Address Line 1": "My House",
"Address Line 2": "My Road",
"Address Line 3": "My Suburb",
"City / Town": "My Town",
"Country": "United Kingdom",
"PostCode": "",
"Creation Date": "24 December 2014"
},
{
"Id": "2",
"NI Number": "NM123405C",
"Full Name": "A Dummy",
"Address Line 1": "Dummy 1",
"Address Line 2": "Dummy 2",
"Address Line 3": "Dummy 3",
"City / Town": "Dummy 4",
"Country": "United Kingdom",
"PostCode": "",
"Creation Date": "09 February 2015"
}

скрипт

for (let i = 0, len = cleanedData.length; i < len; i++) {

let foundDuplicate = false;

if (cleanedData[i]["Duplicate"] === "false" || cleanedData[i]["Duplicate"] === undefined) {

for (let t = i + 1, len = cleanedData.length; t < len; t++) {

if (cleanedData[i]["NI Number"] === cleanedData[t]["NI Number"]) {
foundDuplicate = true;
cleanedData[t]["Duplicate"] = true;
}

}

if (foundDuplicate === true) {
cleanedData[i]["Duplicate"] = true;
} else {
cleanedData[i]["Duplicate"] = false;
}
}

}

Я пытаюсь найти дубликаты "NI Numbers" в 33 000 записей. Номер NI может повторяться несколько раз. В настоящее время скрипт работает так, как ожидалось, но занимает более 70 секунд. Я хотел бы уменьшить это до 35 секунд, если это возможно.

Я новичок в JavaScript, но из того, что я прочитал, используя цикл for с кешированной длиной, это быстрый способ итерации по массиву. Я прочитал эту карту, набор может увеличить производительность, но я не уверен, как реализовать их в моем скрипте.

Есть ли способ повысить производительность моего кода?

спросил(а) 2017-04-28T15:08:00+03:00 3 года, 5 месяцев назад
1
Решение
106

Вы не предоставили какой-либо инструмент для бенчмаркинга, поэтому, надеюсь, следующее поможет.

Вы можете уменьшить количество тестов и выполнять как можно меньше поисковых запросов. Кроме того, некоторые из ваших тестов являются ошибочными, поскольку вы назначаете booleans, но проверяете на строки. Надеюсь, комментариев достаточно.

// Reduce test data to minimum required, increase sample size
var cleanedData = [
{"Id": "1","NI Number": "NG111111A"},
{"Id": "2","NI Number": "NM123405C"}, // Duplicate
{"Id": "3","NI Number": "NM123405D"},
{"Id": "4","NI Number": "NM123405E"}, // Duplicate
{"Id": "5","NI Number": "NM123405C"}, // Duplicate
{"Id": "4","NI Number": "NM123405E"}, // Duplicate
{"Id": "4","NI Number": "NM123405F"},
{"Id": "4","NI Number": "NM123405E"} // Duplicate
];

// Use var for better compatibility unless you really need let
for (var i = 0, iLen = cleanedData.length; i < iLen; i++) {

// Store ref to current object for performance
var obj = cleanedData[i];

// If doesn't have Duplicate property, add and set to false
// Only test if not already marked as a duplicate
if (!('Duplicate' in obj)) {
obj.Duplicate = false;

// Reuse iLen, don't need to get length of array again
for (var t = i + 1; t < iLen; t++) {

// Store ref to test obj for performance
var tObj = cleanedData[t];

// Simplify assignment to both objects if duplicate found
if (obj['NI Number'] === tObj['NI Number']) {
obj.Duplicate = true;
tObj.Duplicate = true;
}
}
}
}

console.log(cleanedData)

Пожалуйста, дайте мне знать, если это помогает. Вы также можете использовать методы массива, такие как forEach, но я думаю, что для циклов, по крайней мере, так быстро и значительно быстрее на некоторых хостах.

Внедрение индекса, предложенного Салманом А, будет выглядеть примерно так: это краткое (ну, на одну строку меньше первого метода) и, скорее всего, довольно быстро, поскольку оно только циклы один раз, но оно делает гораздо больше операций записи в индекс.

var cleanedData = [
{"Id": "1","NI Number": "NG111111A"},
{"Id": "2","NI Number": "NM123405C"}, // Duplicate
{"Id": "3","NI Number": "NM123405D"},
{"Id": "4","NI Number": "NM123405E"}, // Duplicate
{"Id": "5","NI Number": "NM123405C"}, // Duplicate
{"Id": "4","NI Number": "NM123405E"}, // Duplicate
{"Id": "4","NI Number": "NM123405F"},
{"Id": "4","NI Number": "NM123405E"} // Duplicate
];

// Store NI Number value and index first found
var index = {};

for (var i=0, iLen=cleanedData.length; i<iLen; i++) {
var obj = cleanedData[i];
var value = obj['NI Number'];

// If obj doesn't have Duplicate property, add as false
if (!('Duplicate' in obj)) obj.Duplicate = false;

// If value is in index, mark duplicates
if (value in index) {
obj.Duplicate = true;
cleanedData[index[value]].Duplicate = true;

// Otherwise, add value to index
} else {
index[value] = i;
}
}

console.log(cleanedData);

ответил(а) 2017-04-28T15:50:00+03:00 3 года, 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема