Улучшение повторяющегося Finder и для работы Loop
Я создал скрипт, который найдет дубликаты ключа в массиве объектов. Если дубликаты найдены, новый ключ и значение ("Дубликат": истина) добавляются к объектам с повторяющимися значениями ключа.
Пример данных
{
"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 с кешированной длиной, это быстрый способ итерации по массиву. Я прочитал эту карту, набор может увеличить производительность, но я не уверен, как реализовать их в моем скрипте.
Есть ли способ повысить производительность моего кода?
Вы не предоставили какой-либо инструмент для бенчмаркинга, поэтому, надеюсь, следующее поможет.
Вы можете уменьшить количество тестов и выполнять как можно меньше поисковых запросов. Кроме того, некоторые из ваших тестов являются ошибочными, поскольку вы назначаете 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);
Еще в рубрике
- Вопросы
- Duplicates
- Улучшение повторяющегося Finder и для работы Loop