Как ускорихме уеб приложението 20 пъти с WebAssembly

Как ускорихме уеб приложението 20 пъти с WebAssembly

В тази статия се разглежда случай за ускоряване на браузърно приложение чрез замяна на изчисленията с JavaScript с WebAssembly.

Какво е WebAssembly?

Накратко, това е бинарен формат на инструкции за стекова виртуална машина. Често Wasm (съкратено название) се нарича програмен език, но това не е вярно. Форматът на инструкциите се изпълнява в браузъра заедно с JavaScript.

Важно е, че WebAssembly може да бъде получен при компилиране на изходен код на такива езици като C/C++, Rust, Go. Тук се прилага статична типизация и т. нар. плоска модел на паметта. Кодът, както беше споменато, се съхранява в компактния бинарен формат, благодарение на което се изпълнява почти толкова бързо, колкото ако приложението беше стартирано чрез команден ред. Тези възможности доведоха до нарастваща популярност на WebAssembly.

Напомняме: за всички читатели на "Хабра" — отстъпка от 10 000 рубли при записване на всякакъв курс на Skillbox с промокод "Хабр".

Skillbox препоръчва: Практически курс «Мобилен разработчик PRO».

В момента Wasm се използва в много приложения, от игри като Doom 3 до портировани уеб приложения като Autocad и Figma. Wasm се прилага и в такава сфера, като serverless изчисления.

В тази статия е представен пример за използване на Wasm за ускоряване на аналитичен уеб-сервис. За илюстрация взехме работещо приложение, написано на C, което ще бъде компилирано в WebAssembly. Резултатът ще бъде използван за замяна на нископроизводителни части на JS.

Трансформация на приложението

В примера ще се използва браузърен сервис fastq.bio, който е предназначен за генетици. Инструментът позволява оценка на качеството на секвенирането (дешифрирането) на ДНК.

Ето пример за приложението в действие:

Как ускорихме уеб приложението 20 пъти с WebAssembly

Подробности за процеса не е необходимо да се предоставят, тъй като те са доста сложни за неспециалисти, но накратко, учените могат да разберат по указаната по-горе инфографика дали процесът на секвениране на ДНК е протекъл гладко и какви проблеми са се появили.

Този сервис има алтернативи, десктопни програми. Но fastq.bio позволява ускоряване на работата, визуализирайки данните. В повечето други случаи трябва да се знае как да се работи с команден ред, но не на всички генетици е нужен опит.

Всичко работи просто. На входа – данни, представени под формата на текстов файл. Този файл се генерира от специализирани инструменти за секвениране. В файла се съдържа списък с последователности на ДНК и оценка на качеството за всеки нуклеотид. Форматът на файла е .fastq, затова и услугата получи такова наименование.

Имплементация на JavaScript

Първата стъпка на потребителя при работа с fastq.bio е изборът на съответния файл. Използвайки обекта File, приложението прочита произволна извадка от данни от файла и обработва този пакет. Задачата на JavaScript тук е изпълнението на несложни операции с низове и изчисляването на показателите. Един от тях е броят на нуклеотидите A, C, G и T в различни фрагменти на ДНК.

След изчисляването на нужните показатели те се визуализират с помощта на Plotly.js, а услугата започва да работи с нова извадка данни. Разделянето на фрагменти е направено за повишаване на качеството на UX. Ако работите с всички данни наведнъж, процесът ще зацикли за известно време, тъй като файловете с резултатите от секвенирането заемат стотици гигабайти дисково пространство. Услугата обаче взема участъци данни с размер от 0,5 до 1 Мб и работи с тях стъпка по стъпка, изграждайки графични данни.

Ето как работи:

Как ускорихме уеб приложението 20 пъти с WebAssembly

В червения правоъгълник е разположен алгоритъмът за преобразуване на низове за получаване на визуализация. Това е най-високонаградената по отношение на изчисленията част на услугата. Струва си да опитате да я замените с Wasm.

Тестираме WebAssembly

За оценка на възможността за използване на Wasm екипът на проекта се зае с търсене на готови решения за създаване на QC-метрика (QC – quality control) на базата на файлове fastq. Търсенето се проведе сред инструменти, написани на C, C++ или Rust, за да има възможност за портване на кода на WebAssembly. Освен това инструментът не трябва да е "суров", изискваше се услуга, вече проверена от учени.

В резултат на това изборът беше направен в полза на seqtk. Приложението е доста популярно, то е open-source, изходният език е C.

Преди преобразуването в Wasm е добре да се разгледа принципа на компилация на seqtk за десктопа. Според Makefile, ето какво е нужно:

# Compile to binary
$ gcc seqtk.c 
   -o seqtk 
   -O2 
   -lm 
   -lz

В принцип, seqtk може да се компилира с помощта на Emscripten. Ако го нямате, можем да го направим по следния начин с Docker.

$ docker pull robertaboukhalil/emsdk:1.38.26
$ docker run -dt --name wasm-seqtk robertaboukhalil/emsdk:1.38.26

При желание може да го съберете и сами, но това отнема време.

Вътре в контейнера спокойно можете да използвате emcc като алтернатива на gcc:

# Compile to WebAssembly
$ emcc seqtk.c 
    -o seqtk.js 
    -O2 
    -lm 
    -s USE_ZLIB=1 
    -s FORCE_FILESYSTEM=1

Минимални промени:

Вместо изхода в бинарен файл, Emscripten генерира файлове с .wasm и .js, които се използват за стартиране на модула WebAssembly.

За поддръжка на библиотеката zlib се използва флагът USE_ZLIB. Библиотеката е широко разпространена и портирована на WebAssembly, а Emscripten я включва в проекта.

Активира се виртуалната файлова система на Emscripten. Това е POSIX-подобна файлова система, работеща в оперативната памет на браузъра. Когато страницата се обнови, паметта се изчиства.

За да разберете защо е необходима виртуалната файлова система, трябва да сравните начина на стартиране на seqtk от командния ред с начина на стартиране на компилирания модул WebAssembly.

# On the command line
$ ./seqtk fqchk data.fastq
 
# In the browser console
> Module.callMain(["fqchk", "data.fastq"])

Достъпът до виртуалната файлова система е необходим, за да не се пренаписва seqtk за стринг, а не файлов вход. В този случай фрагментът от данни се представя като файл data.fastq във виртуалната файлова система с извикване на main() seqtk.

Ето новата архитектура:

Как ускорихме уеб приложението 20 пъти с WebAssembly

Илюстрацията показва, че вместо изчисления в основния поток на браузъра се използват WebWorkers. Този метод позволява извършване на изчисления в фонов поток, без да се влошава отзивчивостта на браузъра. А контролерът на WebWorker стартира Worker, управлявайки неговата интеграция с основния поток.

Командата seqtk се стартира чрез Worker на монтирания файл. След приключването на работата, Worker предава резултата под формата на Promise. Когато съобщението бъде получено от основния поток, резултатът се използва за актуализиране на графиките. И така, в няколко итерации.

Какво ще кажете за производителността на WebAssembly?

За да оценят промяната в производителността, екипът на проекта е използвал параметъра за брой операции за четене в секунда. Времето за изграждане на интерактивни графики не се отчита, тъй като и в двете имплементации се използва JavaScript.

При използване на решение "извън кутията" повишението в производителността е девет пъти.

Как ускорихме уеб приложението 20 пъти с WebAssembly

Това е отличен резултат, но, както се оказа, съществува възможност за оптимизиране и на него. Фактът е, че голям брой резултати от QC-анализа не се използват от seqtk и затова могат да бъдат премахнати. Ако направим това, резултатът в сравнение с JavaScript се подобрява 13 пъти.

Как ускорихме уеб приложението 20 пъти с WebAssembly

Постигна се с просто коментиране на командите printf().

Но и това не е всичко. Важно е, че на този етап fastq.bio получава резултати от анализа чрез извикване на различни функции на C. Всяка от тях изчислява свой набор от характеристики, така че всеки фрагмент от файла се чете два пъти.

За да заобиколим този проблем, беше решено да се комбинират две функции в една. В резултат на това производителността се увеличи 20 пъти.

Как ускорихме уеб приложението 20 пъти с WebAssembly

Трябва да подчертаем, че подобен забележителен резултат не може да бъде постигнат винаги. В някои случаи производителността намалява, така че е важно да се оценява всеки конкретен случай.

В заключение може да се каже, че Wasm наистина предоставя възможност за подобряване на производителността на приложението, но трябва да се използва разумно.

Skillbox препоръчва:

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster