Как не программист, вероятно, написал самую быструю библиотеку в мире
Привет, Хабр! Не редко захожу, читаю, пришло время поделиться собственным опытом и маленьким поводом для гордости — только что я написал библиотеку, которая примерно в 33 раза быстрее, чем все иные решения, что я находил.
Вот сразу ссылка
Что же за библиотека и зачем нужна?
Она преобразует xlsx в csv. Причём данная библиотека является совместимой с JS/TS, в ближайшее время портирую на питон.
Зачем нужна? Всё на деле просто — понадобилось мне работать с таблицами Excel. Выбор, казалось бы, очевиден — пандас. Вещь мощная, но есть у неё проблема — очень медленная. На то, чтобы открыть xlsx файл размером 600 кбайт, ничего с ним не делая, уходит порядка 0.2 секунды.
Вроде немного, однако задача передо мной стояла в следующем — написать чат-бота, который будет сканировать xlsx документы и выдавать пользователям по ним информацию. Пользователей ожидается 200 штук, и вопрос — сколько времени уйдёт у бота, чтобы обработать их одновременно?
Кроме того, я в последнее время овладеваю TypeScript, ботов пишу на нём, потому не хотелось бы «отходить от кассы». Там можно работать с датафреймами, с помощью библиотеки Polars, однако она не умеет читать .xlsx, только .csv.
И как быть? Правильно, писать самому. Выбор по ряду причин (главная из которых — это прикольно и быстро) пал на Rust. Тем более, там присутствует NAPI.
Дальше я нагуглил библиотеку calamine, и тупо из примеров разработчика взял кусок кода.
После чего потратил несколько часов, чтобы понять, как это всё заставить работать. Дошло до смешного — утром у меня все файлы создавались корректно, но ближе к вечеру некоторые файлы создавались с ошибкой JSON, которая не искалась нигде. Удалял проект, создавал заново, понижал версию утилит — ничего не помогало. Но стоило переключиться с Windows на Ubuntu, как всё прошло. Магия.
Потому, вместо мучений и установки раста с последующей компиляцией, Вы можете установить прекомпилированный файл прямо отсюда. Предупреждаю — пока только под линукс! Под винду и мак будет готово в течение пары дней.
Ну, на этом разработка как бы всё. Теперь самое вкусное — тесты. Почему я считаю мою библиотеку, вероятно, самой быстрой в мире?
Для начала — определимся с «конкурентами». Их два.
python: xlsx2csv (через него, вроде как, работает пандас)
JS/TS: xlsx
Для начала — вот такой скриншот
Как видите, потоки крайне активно используются. На чтение и запись csv 10.000 раз ушло 34 секунды. Для справки, я сижу с Sata SSD, скорости на линейное чтение там порядка 500 мбайт в секунду. Xlsx весит 250 кбайт, CSV 650, в сумме почти 1 мбайт. Множим на 10.000, получается 10 гигов, или 18–20 секунд тупо на ввод-вывод =) Для справки, мой конфиг на скринфетче ниже
Что предлагают конкуренты? Ну, ждать, когда завершатся все операции, желания немного, можете сами удостовериться. Потому программы были запущены на те же 34 секунды с указателем, какая по счёту операция.
Результаты: около 330 файлов у xlsx и около 280 у xlsx2csv. Получается, моя библиотека примерно в 33 раза быстрее, чем у конкурентов =)
Разумеется, библиотека не идеальная. В частности, у неё есть неприятная особенность — когда сканируется дата, то переводится в числовой формат. На деле не удивительно, потому что время — по сути числовой формат. А CSV воспринимает только текст. Там вообще нет типов данных, просто символы. А если сконвертировать в строчку, по-типу »01–02–2024», то это создаст новую проблему — в США сначала идёт месяц, а потом день, у нас же сначала день, а потом месяц. И »01–02–2024» они прочитают не как 1 февраля 24 го, а как 2 января. И у меня нет идей, как решать такое. А какие у Вас есть мысли?
На этом всё, спасибо за прочтение.