Я разрабатываю синтаксический анализатор CSV, который должен иметь возможность обрабатывать огромные наборы данных (читать 10 миллионов строк) в браузере.
В основном парсер работает следующим образом:
Основной поток читает кусок размером 20 МБ, иначе браузер быстро рухнет. После этого отправляет прочитанный кусок данных одному из воркеров.
Рабочий получает данные и отбрасывает столбцы, которые мне не нужны, и сохраняет те, которые мне нужны. Обычно мне нужны только 4-5 столбцов из 20-30.
Рабочий процесс отправляет обработанные данные обратно в основной поток.
Основной поток получает данные и сохраняет их в массиве данных.
Повторяйте шаги 1-4, пока файл не будет готов.
В конце с набором данных (преступления города chicago), я получаю массив, внутри которого находится 71 другой массив, и каждый из этих массивов содержит +/- 90 000 элементов. Каждый из этих 90К элементов содержит 5 строк (столбцов, взятых из прочитанного файла). А именно широта, долгота, год, блок и IUCR.
Подводя итог, 71 — это количество фрагментов по 20 МБ в наборе данных, 90 КБ — количество строк в каждом фрагменте по 20 МБ, а 5 — это извлеченные столбцы.
Я заметил, что браузер (Chrome) использует слишком много памяти, поэтому я попробовал в 4 разных браузерах (Chrome, Opera, Vivaldi и Firefox) и записал память, используемую вкладкой.
- Хром — 1,76 ГБ
- Опера - 1,76 ГБ
- Фаерфокс — 1,3 ГБ
- Вивальди - 1 ГБ
Если я попытаюсь воссоздать тот же массив, но с фиктивными данными, он использует только прибл. 350 МБ памяти.:
var data = [];
for(let i = 0; i < 71; i++){
let rows = [];
for(let j = 0; j < 90*1000; j++){
rows.push(["029XX W MADISON ST", "2027", "-87.698850575", "2001", "41.880939487"])
}
data.push(rows);
}
Я понимаю, что если массив статический, как показано в приведенном выше коде, его легче выполнить лучше, чем динамический случай. Но я не ожидал использовать в 5 раз больше памяти для того же количества данных.
Что я могу сделать, чтобы использовать меньше памяти в синтаксическом анализаторе?