
Base64 — это схема кодирования двоичных значений в текст, преобразующая произвольные двоичные данные (например, изображения, файлы или любые байтовые последовательности) в безопасную печатную ASCII-строку, состоящую из 64-символьного алфавита (A–Z, a–z, 0–9, +, /). Браузеры применяют эту схему в JavaScript для встраивания двоичных данных непосредственно в код/HTML или для передачи двоичных данных в виде текста.
Недавно в браузерах появились удобные и безопасные функции для обработки Base64: Uint8Array.toBase64() и Uint8Array.fromBase64(). Хоть у них и есть множество параметров, смысл их сводится к кодированию и декодированию.
const b64 = Uint8Array.toBase64(bytes); // Строка
const recovered = Uint8Array.fromBase64(b64); // Uint8Array
При кодировании они берут 24 бита из входных данных и разделяют их на четыре сегмента по 6 бит, и каждое 6-битное значение (в интервале от 0 до 63) соотносится с конкретным символом из алфавита Base64: первые 26 символов — это буквы A-Z в верхнем регистре, следующие 26 — a-z в нижнем, затем идут цифры 0-9 и, наконец, символы «+» и «/» в качестве 62-го и 63-го символов. Если длина входных данных не кратна трём байтам, то в качестве заполнителя используется знак «=».
Насколько же быстро могут работать эти функции?
Допустим, мы потребляем 3 байта и генерируем 4 байта на такт CPU. При частоте процессора 4,5 ГГц мы должны выполнять кодирование в Base64 со скоростью 13,5 ГБ/с. В противоположном направлении следует ожидать меньшей производительности. При кодировании допустим любой ввод, то есть подойдут любые двоичные данные. При декодировании же мы должны обрабатывать ошибки и пропускать пробелы.
Я написал браузерный бенчмарк. Можете попробовать его сами в своём браузере.
Я решил протестировать его на своём процессоре Apple M4, чтобы проверить, насколько быстро способны работать разные браузеры. Использовались блоки по 64 КиБ. Скорость замерена относительно двоичных данных.
Браузер |
Скорость кодирования |
Скорость декодирования |
|---|---|---|
Safari |
17 ГБ/с |
9,4 ГБ/с |
SigmaOS |
17 ГБ/с |
9,4 ГБ/с |
Chrome |
19 ГБ/с |
4,6 ГБ/с |
Edge |
19 ГБ/с |
4,6 ГБ/с |
Brave |
19 ГБ/с |
4,6 ГБ/с |
Servo |
0,34 ГБ/с |
0,40 ГБ/с |
Firefox (старый) |
0,34 ГБ/с |
0,40 ГБ/с |
Firefox (версия 146) |
2,2 ГБ/с |
2,6 ГБ/с |

Похоже, Safari выполняет кодирование чуть медленнее, чем браузеры на основе Chromium (Chrome, Edge, Brave), однако декодирует почти вдвое быстрее. Servo и Firefox справляются почти одинаково плохо; неожиданно было то, что декодирование они выполняют быстрее, чем кодирование. (В новых версиях Firefox, выпущенных после публикации этого поста, производительность лучше.) Можно было бы проверить и другие браузеры, но большинство из них создано на основе Chromium или WebKit.
Для понимания контекста скажу, что накопитель хорошего ноутбука способен поддерживать скорость чтения или записи более 3 ГБ/с. Накопители некоторых дорогих ноутбуков быстрее 5 ГБ/с. Теоретически, WiFi-соединение стандарта Wifi 7 может быть близким к 5 ГБ/с. Некоторые Интернет-провайдеры могут приближаться к обеспечению сравнимых сетевых скоростей, однако ваше Интернет-соединение, скорее всего, во много раз медленнее.
Скорости в большинстве браузеров выше, чем можно было бы наивно предположить. Они быстрее, чем сети и SSD.
Примечание 1. Более низкие скорости декодирования в Chromium-браузерах, похоже, зависят от движка JavaScript V8, который сначала декодирует строку во временный буфер, а уже потом выполняет копирование из этого временного буфера в конечную точку. (См. BUILTIN(Uint8ArrayFromBase64) в v8/src/builtins/builtins-typed-array.cc.)
Примечание 2. Дэнис Палмейро из Mozilla сообщил мне, что ближайшие изменения в Firefox повысят производительность функций Base64. В таблицу выше добавлены новые значения.
ky0
Потом люди читают и такие - "ой, ну нет, фу, не буду я Фаерфоксом пользоваться - он всего 2 гигабита base64 выдаёт".
qw1
Логично, что если случайно выбранная функция оказалась хорошо оптимизированной, то и соседние функции тоже. Значит, авторы браузера в принципе уделяют внимание оптимизациям.
rimidalvv
Честно? Не очень логично. Люди разные пишут. Люди приходят и уходят. Если кто-то написал когда-то что-то не совсем оптимально, то это ещё не значит что всё остальное такое же. И наоборот, если одна функция написана хорошо, то это не значит что и всё приложение написано также
qw1
Если функция написана хорошо, есть шанс, что и некоторые другие функции, написаны им же, тоже хорошо.
При прочих равных, если в одном приложении что-то сделано лучше чем в другом, и ничего больше об этих приложениях не известно, первое приложение выигрывает.
sic
Для меня вообще как-то несамоочевидно, зачем через base64 гигабайты гонять. Так что о других функциях это мало что говорит (и бенчмарки этих других функций имеются, показывая, что далеко не все так однозначно).