Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 Контент вільний від AI. Цей пост на 100% написаний людиною, як і все на моєму блозі. Насолоджуйтесь!

30.08.2023

Ruby - не найкраща скриптова мова, якщо працюєш з великими файлами

Невеликий сюжет з сьогоднішньої практики. Потрібно було загнати близько 5 мільйонів рядків JSON з файлу в OpenSearch… тільки не по одному — бо зовсім довго — а пачками. Файл займає 2 ГБ, відповідно рядки десь по 400 байтів кожний, але довжина змінна (в кожному рядку — обʼєкт JSON.) До речі, в GZip цей же ж файл займає тільки 70 МБ. Стискайте ваш JSON!

Почав робити це на Ruby - бо простіше за все. Відкрив файл, читаєш собі методом each_line, збираєш пакет та відправляєш. От тільки чомусь працювало це дуже повільно. Пакет з 10 Мб збирався близько хвилини.

Подумав, що може each_line повільно читає, бо йому треба шукати на перенесення рядка. Спробував прочитати весь файл — методом readlines, а потім вже спокійно їх обробляти. Це ситуацію не покращило. Моя підозра лягла на виділення памʼяті при наборі пакета.

Тоді, думаю, скрипт дуже простий — перепишу його на Go. Тут теж є bufio#ReadLine. А головне, що в Go можна виділити памʼять для всього буфера одноразово, а потім потроху його наповнювати. Для цього є третій аргумент функції make: зарезервована місткість.

Далі все пішло добре та після декількох експериментів документи були імпортовані. Для мене висновком стало те, що, якщо вже потрібно обробити такий великий файл, то можна відразу писати скрипт на Go та уникнути проблем з памʼяттю.

(До речі. На Ruby моєю помилкою було те, що я відразу збирав пакет в один рядок. Це й призводить до зайвого виділення памʼяті. Вирішити можна так: збирати рядки в масив, а потім єднати операцією join. Але, на мою думку, урок залишається.)