
In dit artikel bespreken we een case over het versnellen van een browserapplicatie door berekeningen in JavaScript te vervangen door WebAssembly.
WebAssembly - wat is het?
Kort gezegd is het een binaire instructie-indeling voor een stack-gebaseerde virtuele machine. Vaak wordt Wasm (de afgekorte naam) een programmeertaal genoemd, maar dat klopt niet. De instructie-indeling wordt uitgevoerd in de browser, samen met JavaScript.
Belangrijk is dat WebAssembly kan worden verkregen door broncode op talen zoals C/C++, Rust, Go te compileren. Hier wordt statistische typechecking toegepast en een zogenaamde platte geheugenschema. De code, zoals hierboven vermeld, wordt opgeslagen in een compacte binaire indeling, waardoor deze bijna net zo snel wordt uitgevoerd als wanneer de applicatie via de opdrachtregel zou worden gestart. Deze mogelijkheden hebben geleid tot de groeiende populariteit van WebAssembly.
Ter herinnering: voor alle lezers van «Habr» — een korting van 10.000 roebel bij inschrijving voor elke cursus van Skillbox met de promocode «Habr».
Skillbox raadt aan: Praktische cursus .
Momenteel wordt Wasm gebruikt in veel applicaties, van spellen zoals Doom 3 tot webapplicaties zoals Autocad en Figma. Wasm wordt ook toegepast in een veld zoals serverless computing.
In dit artikel wordt een voorbeeld gegeven van het gebruik van Wasm om een analytische webservice te versnellen. Voor de duidelijkheid hebben we een werkende applicatie in C genomen, die in WebAssembly kan worden gecompileerd. Het resultaat zal worden gebruikt om de minder presterende delen van JS te vervangen.
Transformatie van de applicatie
In het voorbeeld gebruiken we de browserdienst fastq.bio, die bedoeld is voor geneticus. De tool maakt het mogelijk om de kwaliteit van DNA-sequencing te beoordelen.
Hier is een voorbeeld van de applicatie in actie:

De details van het proces hoeven niet te worden gepresenteerd, aangezien ze vrij gecompliceerd zijn voor leken, maar in het kort kunnen wetenschappers op basis van de hierboven genoemde infographic begrijpen of het proces van DNA-sequencing soepel verliep en welke problemen zich hebben voorgedaan.
Deze dienst heeft alternatieven, desktopprogramma's. Maar fastq.bio maakt het mogelijk om de verwerking te versnellen door gegevens te visualiseren. In de meeste andere gevallen heb je ervaring met de opdrachtregel nodig, maar niet alle geneticus beschikt over de benodigde ervaring.
Het werkt heel eenvoudig. Aan de ingang staan gegevens, gepresenteerd als een tekstbestand. Dit bestand wordt gegenereerd door gespecialiseerde tools voor sequencing. In het bestand staat een lijst van DNA-sequenties en een kwaliteitsbeoordeling voor elke nucleotide. Het bestandformaat is .fastq, daarom heeft de dienst deze naam gekregen.
Implementatie in JavaScript
De eerste stap voor de gebruiker bij het werken met fastq.bio is het kiezen van het juiste bestand. Met behulp van het File-object leest de applicatie een willekeurige steekproef uit het bestand en verwerkt deze batch. De taak van JavaScript hier is het uitvoeren van eenvoudige stringoperaties en het berekenen van statistieken. Een daarvan is het aantal nucleotiden A, C, G en T in verschillende DNA-fragmenten.
Na het berekenen van de benodigde statistieken worden deze gevisualiseerd met behulp van Plotly.js, en de dienst begint te werken met een nieuwe steekproef gegevens. Het splitsen in fragmenten is gedaan om de kwaliteit van de gebruikerservaring te verbeteren. Als je met alle gegevens tegelijk werkt, hangt het proces enige tijd vast, aangezien de bestanden met sequenceresultaten honderden gigabytes aan opslagruimte vereisen. De dienst neemt echter datastukken van 0,5 tot 1 MB en werkt stap voor stap met hen, waarbij grafische gegevens worden opgebouwd.
Zo werkt het:

In de rode rechthoek staat het algoritme voor stringtransformaties om visualisatie te maken. Dit is het meest veeleisende deel van de dienst qua berekeningen. Probeer het eens te vervangen door Wasm.
WebAssembly testen
Om de mogelijkheid van het gebruik van Wasm te evalueren, heeft het projectteam gezocht naar kant-en-klare oplossingen voor het maken van QC-statistieken (QC - quality control) op basis van fastq-bestanden. De zoektocht vond plaats onder tools, geschreven in C, C++ of Rust, zodat de mogelijkheid bestond om de code naar WebAssembly te porteren. Bovendien mocht de tool niet 'onvolwassen' zijn; er was een service vereist die al door wetenschappers was getest.
Uiteindelijk werd er gekozen voor . De applicatie is redelijk populair, het is open-source en de oorspronkelijk geschreven taal is C.
Voordat je het in Wasm omzet, moet je het compilatieprincipe van seqtk voor de desktop bekijken. Volgens het Makefile is dit wat je nodig hebt:
# Compile to binary
$ gcc seqtk.c
-o seqtk
-O2
-lm
-lzIn principe kan seqtk worden gecompileerd met behulp van Emscripten. Als je dat niet hebt, komen we met .
$ docker pull robertaboukhalil/emsdk:1.38.26
$ docker run -dt --name wasm-seqtk robertaboukhalil/emsdk:1.38.26Als je wilt, , maar daar heb je tijd voor nodig.
Binnen de container kan emcc zonder problemen als alternatief voor gcc worden gebruikt:
# Compile to WebAssembly
$ emcc seqtk.c
-o seqtk.js
-O2
-lm
-s USE_ZLIB=1
-s FORCE_FILESYSTEM=1Minimale wijzigingen:
In plaats van uitvoer naar een binaire bestand, gebruikt Emscripten .wasm en .js om bestanden te genereren die worden gebruikt voor het uitvoeren van de WebAssembly-module.
Voor ondersteuning van de zlib-bibliotheek wordt de vlag USE_ZLIB gebruikt. De bibliotheek is wijdverspreid en naar WebAssembly gepoord, en Emscripten voegt deze toe aan het project.
De virtuele bestandssysteem van Emscripten wordt geactiveerd. Dit is , dat werkt in het geheugen binnen de browser. Wanneer de pagina wordt vernieuwd, wordt het geheugen gewist.
Om te begrijpen waarom een virtueel bestandssysteem nodig is, is het nuttig om de manier van uitvoeren van seqtk vanuit de commandoregel te vergelijken met de uitvoering van de gecompileerde WebAssembly-module.
# On the command line
$ ./seqtk fqchk data.fastq
# In the browser console
> Module.callMain(["fqchk", "data.fastq"])Toegang tot het virtuele bestandssysteem is nodig om seqtk niet opnieuw te schrijven voor string- in plaats van bestandinvoer. In dit geval wordt het gegevensfragment weergegeven als het bestand data.fastq in het virtuele FS met een aanroep van main() seqtk.
Hier is de nieuwe architectuur:

De afbeelding laat zien dat in plaats van berekeningen in de hoofdthread van de browser, er gebruik wordt gemaakt van . Deze methode maakt het mogelijk om berekeningen in de achtergrondthread uit te voeren, zonder de responsiviteit van de browser te verminderen. De WebWorker-controller start de Worker en beheert de interactie met de hoofdthread.
De seqtk-opdracht wordt uitgevoerd met behulp van de Worker op het aangekoppelde bestand. Na het voltooien van de uitvoering geeft de Worker het resultaat in de vorm van een Promise. Wanneer het bericht door de hoofdthread is ontvangen, wordt het resultaat gebruikt om de grafieken bij te werken. Dit gebeurt in meerdere iteraties.
Hoe zit het met de prestaties van WebAssembly?
Om de wijziging in prestaties te evalueren, maakte het projectteam gebruik van de parameter aantal leesbewerkingen per seconde. De tijd voor het bouwen van interactieve grafieken wordt niet meegerekend, omdat in beide implementaties JavaScript wordt gebruikt.
Bij gebruik van de ‘out-of-the-box’-oplossing was er een prestatieverbetering van negen keer.

Dit is een uitstekend resultaat, maar het blijkt dat er ook mogelijkheden zijn om dit verder te optimaliseren. Veel resultaten van de QC-analyse worden niet gebruikt door seqtk, dus deze kunnen worden verwijderd. Als dit wordt gedaan, verbetert het resultaat ten opzichte van JS met dertien keer.

Dit werd bereikt door simpelweg printf()-opdrachten te kommentariëren.
Maar dat is nog niet alles. Het feit is dat fastq.bio op dit punt de analyset resultaten ontvangt met aanroepen van verschillende C-functies. Elke functie berekent zijn eigen set kenmerken, zodat elk fragment van het bestand twee keer is gelezen.
Om dit probleem te omzeilen, werd besloten om twee functies in één te combineren. Als gevolg daarvan is de prestaties met 20 keer toegenomen.

Het is vermeldenswaard dat zo'n uitzonderlijk resultaat niet altijd kan worden bereikt. In sommige gevallen daalt de prestaties, dus het is belangrijk om elk specifiek geval te evalueren.
Als conclusie kan worden gesteld dat Wasm inderdaad de mogelijkheid biedt om de prestaties van de applicatie te verbeteren, maar het gebruik ervan moet doordacht zijn.
Skillbox raadt aan:
- Praktische tweejarenopleiding .
- Online cursus .
- Praktische jaaropleiding .
Bron: habr.com
