Как не программист, вероятно, написал самую быструю библиотеку в мире
- пятница, 3 ноября 2023 г. в 00:00:19
Привет, Хабр! Не редко захожу, читаю, пришло время поделиться собственным опытом и маленьким поводом для гордости - только что я написал библиотеку, которая примерно в 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 января. И у меня нет идей, как решать такое. А какие у Вас есть мысли?
На этом всё, спасибо за прочтение.