Cómo utilizamos WebAssembly para acelerar nuestra aplicación web hasta 20 veces (estudio de caso)

 

 

 


Índice
  1. Fondo
  2. fastq.bio: la implementación de JavaScript
  3. fastq.bio: la implementación de WebAssembly
  4. Optimización del rendimiento
  5. Una palabra de precaución
  6. Conclusión
    1. Otras lecturas

En este artículo, exploramos cómo podemos acelerar las aplicaciones web reemplazando los cálculos lentos de JavaScript con WebAssembly compilado.

 

Si no lo has oído, aquí tienes el TL;DR: WebAssembly es un nuevo lenguaje que se ejecuta en el navegador junto con JavaScript. Sí, eso es correcto. ¡JavaScript ya no es el único lenguaje que se ejecuta en el navegador!

Pero más allá de simplemente “no ser JavaScript”, su factor distintivo es que puede compilar código de lenguajes como C/C++/Rust (¡ y más! ) en WebAssembly y ejecutarlos en el navegador. Debido a que WebAssembly se escribe estáticamente, utiliza una memoria lineal y se almacena en un formato binario compacto, también es muy rápido y eventualmente podría permitirnos ejecutar código a velocidades "casi nativas", es decir, a velocidades cercanas a las que usted utiliza. d get ejecutando el binario en la línea de comando. La capacidad de aprovechar las herramientas y bibliotecas existentes para su uso en el navegador y el potencial asociado de aceleración son dos razones que hacen que WebAssembly sea tan atractivo para la web.

Hasta ahora, WebAssembly se ha utilizado para todo tipo de aplicaciones, desde juegos (por ejemplo, Doom 3 ) hasta portar aplicaciones de escritorio a la web (por ejemplo, Autocad y Figma ). Incluso se utiliza fuera del navegador, por ejemplo como lenguaje eficiente y flexible para informática sin servidor .

Este artículo es un estudio de caso sobre el uso de WebAssembly para acelerar una herramienta web de análisis de datos. Con ese fin, tomaremos una herramienta existente escrita en C que realiza los mismos cálculos, la compilaremos en WebAssembly y la usaremos para reemplazar los cálculos lentos de JavaScript.

Nota : Este artículo profundiza en algunos temas avanzados como la compilación de código C, pero no te preocupes si no tienes experiencia con eso; aún podrá seguirlo y tener una idea de lo que es posible con WebAssembly.

Fondo

La aplicación web con la que trabajaremos es fastq.bio , una herramienta web interactiva que proporciona a los científicos una vista previa rápida de la calidad de sus datos de secuenciación de ADN; La secuenciación es el proceso mediante el cual leemos las “letras” (es decir, nucleótidos) en una muestra de ADN.

Aquí hay una captura de pantalla de la aplicación en acción:

Una captura de pantalla de fastq.bio en acción ( vista previa grande )

No entraremos en detalles de los cálculos, pero en pocas palabras, los gráficos anteriores brindan a los científicos una idea de qué tan bien fue la secuenciación y se utilizan para identificar problemas de calidad de los datos de un vistazo.

Aunque hay docenas de herramientas de línea de comandos disponibles para generar dichos informes de control de calidad, el objetivo de fastq.bio es brindar una vista previa interactiva de la calidad de los datos sin salir del navegador. Esto es especialmente útil para los científicos que no se sienten cómodos con la línea de comando.

La entrada a la aplicación es un archivo de texto sin formato que genera el instrumento de secuenciación y contiene una lista de secuencias de ADN y una puntuación de calidad para cada nucleótido en las secuencias de ADN. El formato de ese archivo se conoce como “FASTQ”, de ahí el nombre fastq.bio.

Si tiene curiosidad sobre el formato FASTQ (no es necesario comprender este artículo), consulte la página de Wikipedia sobre FASTQ. (Advertencia: se sabe que el formato de archivo FASTQ induce facepalms).

fastq.bio: la implementación de JavaScript

En la versión original de fastq.bio, el usuario comienza seleccionando un archivo FASTQ de su computadora. Con el Fileobjeto, la aplicación lee una pequeña porción de datos comenzando en una posición de byte aleatoria (usando la API FileReader ). En esa porción de datos, usamos JavaScript para realizar manipulaciones básicas de cadenas y calcular métricas relevantes. Una de esas métricas nos ayuda a rastrear cuántas A, C, G y T vemos normalmente en cada posición a lo largo de un fragmento de ADN.

Una vez que se calculan las métricas para ese fragmento de datos, trazamos los resultados de forma interactiva con Plotly.js y pasamos al siguiente fragmento del archivo. La razón para procesar el archivo en pequeños fragmentos es simplemente mejorar la experiencia del usuario: procesar todo el archivo a la vez llevaría demasiado tiempo, porque los archivos FASTQ generalmente tienen cientos de gigabytes. Descubrimos que un tamaño de fragmento entre 0,5 MB y 1 MB haría que la aplicación fuera más fluida y devolvería información al usuario más rápidamente, pero este número variará dependiendo de los detalles de su aplicación y de cuán pesados ​​sean los cálculos.

La arquitectura de nuestra implementación de JavaScript original fue bastante sencilla:

La arquitectura de la implementación JavaScript de fastq.bio ( vista previa grande )

El cuadro en rojo es donde realizamos las manipulaciones de cadenas para generar las métricas. Ese cuadro es la parte de la aplicación que requiere más computación, lo que naturalmente la convirtió en un buen candidato para la optimización del tiempo de ejecución con WebAssembly.

 

fastq.bio: la implementación de WebAssembly

Para explorar si podíamos aprovechar WebAssembly para acelerar nuestra aplicación web, buscamos una herramienta disponible que calcule métricas de control de calidad en archivos FASTQ. Específicamente, buscábamos una herramienta escrita en C/C++/Rust que pudiera portar a WebAssembly y que ya estuviera validada y confiable por la comunidad científica.

Después de investigar un poco, decidimos optar por seqtk , una herramienta de código abierto de uso común escrita en C que puede ayudarnos a evaluar la calidad de los datos de secuenciación (y que generalmente se usa para manipular esos archivos de datos).

Antes de compilar en WebAssembly, primero consideremos cómo compilaríamos normalmente seqtk en binario para ejecutarlo en la línea de comandos. Según el Makefile, este es el gccencantamiento que necesitas:

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

Por otro lado, para compilar seqtk en WebAssembly, podemos usar la cadena de herramientas Emscripten , que proporciona reemplazos directos para las herramientas de compilación existentes para facilitar el trabajo en WebAssembly. Si no tiene Emscripten instalado, puede descargar una imagen de Docker que preparamos en Dockerhub que tiene las herramientas que necesitará (también puede instalarla desde cero , pero eso generalmente lleva un tiempo): ¿QUÉ SARTÉN COMPRAR? Comparativa, precios y análisis de LAS MEJORES SARTENES

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

Dentro del contenedor, podemos usar el emcccompilador como reemplazo de gcc:

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

Como puede ver, las diferencias entre compilar en binario y WebAssembly son mínimas:

  1. En lugar de que la salida sea el archivo binario seqtk, le pedimos a Emscripten que genere un .wasmy un .jsque maneje la creación de instancias de nuestro módulo WebAssembly.
  2. Para admitir la biblioteca zlib, usamos la bandera USE_ZLIB; zlib es tan común que ya se ha portado a WebAssembly y Emscripten lo incluirá en nuestro proyecto.
  3. Habilitamos el sistema de archivos virtual de Emscripten, que es un sistema de archivos similar a POSIX ( código fuente aquí ), excepto que se ejecuta en la RAM dentro del navegador y desaparece cuando actualiza la página (a menos que guarde su estado en el navegador usando IndexedDB, pero eso es para otro artículo).

¿Por qué un sistema de archivos virtual? Para responder a eso, comparemos cómo llamaríamos a seqtk en la línea de comando con el uso de JavaScript para llamar al módulo WebAssembly compilado:

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

Tener acceso a un sistema de archivos virtual es poderoso porque significa que no tenemos que reescribir seqtk para manejar entradas de cadenas en lugar de rutas de archivos. Podemos montar un fragmento de datos como archivo data.fastqen el sistema de archivos virtual y simplemente llamar a la función seqtk main()en él.

 

Con seqtk compilado en WebAssembly, aquí está la nueva arquitectura fastq.bio:

Arquitectura de la implementación WebAssembly + WebWorkers de fastq.bio ( vista previa grande )

Como se muestra en el diagrama, en lugar de ejecutar los cálculos en el hilo principal del navegador, utilizamos WebWorkers , que nos permiten ejecutar nuestros cálculos en un hilo en segundo plano y evitan afectar negativamente la capacidad de respuesta del navegador. Específicamente, el controlador WebWorker inicia el Worker y gestiona la comunicación con el hilo principal. Del lado del trabajador, una API ejecuta las solicitudes que recibe.

Luego podemos pedirle al trabajador que ejecute un comando seqtk en el archivo que acabamos de montar. Cuando seqtk termina de ejecutarse, el trabajador envía el resultado al hilo principal a través de una Promesa. Una vez que recibe el mensaje, el hilo principal utiliza el resultado resultante para actualizar los gráficos. De manera similar a la versión de JavaScript, procesamos los archivos en fragmentos y actualizamos las visualizaciones en cada iteración.

Optimización del rendimiento

Para evaluar si el uso de WebAssembly sirvió de algo, comparamos las implementaciones de JavaScript y WebAssembly utilizando la métrica de cuántas lecturas podemos procesar por segundo. Ignoramos el tiempo que lleva generar gráficos interactivos, ya que ambas implementaciones utilizan JavaScript para ese propósito.

Fuera de la caja, ya vemos una aceleración de ~9X:

Al usar WebAssembly, vemos una aceleración 9 veces mayor en comparación con nuestra implementación de JavaScript original. ( Vista previa grande )

Esto ya es muy bueno, dado que fue relativamente fácil de lograr (¡eso es una vez que entiendes WebAssembly!).

A continuación, notamos que, aunque seqtk genera muchas métricas de control de calidad generalmente útiles, nuestra aplicación no utiliza ni representa gráficamente muchas de estas métricas. Al eliminar algunos de los resultados de las métricas que no necesitábamos, pudimos ver una aceleración aún mayor de 13 veces:

Eliminar resultados innecesarios nos brinda una mayor mejora del rendimiento. ( Vista previa grande )

Nuevamente, esto es una gran mejora dado lo fácil que fue lograrlo: literalmente comentando declaraciones printf que no eran necesarias.

Finalmente, hay una mejora más que analizamos. Hasta ahora, la forma en que fastq.bio obtiene las métricas de interés es llamando a dos funciones C diferentes, cada una de las cuales calcula un conjunto diferente de métricas. Específicamente, una función devuelve información en forma de histograma (es decir, una lista de valores que agrupamos en rangos), mientras que la otra función devuelve información en función de la posición de la secuencia de ADN. Desafortunadamente, esto significa que el mismo fragmento de archivo se lee dos veces, lo cual no es necesario.

Así que fusionamos el código de las dos funciones en una función, aunque desordenada (¡sin siquiera tener que repasar mi C!). Dado que las dos salidas tienen diferentes números de columnas, hicimos algunas discusiones en el lado de JavaScript para desenredar las dos. Pero valió la pena: ¡al hacerlo pudimos lograr una aceleración 20X!

Finalmente, modificar el código de manera que solo leamos cada fragmento de archivo una vez nos brinda una mejora de rendimiento 20 veces. ( Vista previa grande )

Una palabra de precaución

Ahora sería un buen momento para hacer una advertencia. No espere obtener siempre una aceleración 20 veces mayor cuando utilice WebAssembly. Es posible que solo obtengas una aceleración 2X o una aceleración del 20%. O puede sufrir una ralentización si carga archivos muy grandes en la memoria o requiere mucha comunicación entre WebAssembly y JavaScript.

Conclusión

En resumen, hemos visto que reemplazar los cálculos lentos de JavaScript con llamadas a WebAssembly compilado puede generar aceleraciones significativas. Dado que el código necesario para esos cálculos ya existía en C, obtuvimos el beneficio adicional de reutilizar una herramienta confiable. Como también mencionamos, WebAssembly no siempre será la herramienta adecuada para el trabajo (¡ jadea! ), así que úsala sabiamente.

Otras lecturas

  • “ Sube de nivel con WebAssembly ”, Robert Aboukhalil
    Una guía práctica para crear aplicaciones WebAssembly.
  • Aioli (en GitHub)
    Un marco para crear herramientas web genómicas rápidas.
  • Código fuente fastq.bio (en GitHub)
    Una herramienta web interactiva para el control de calidad de los datos de secuenciación de ADN.
  • “ Una introducción resumida en dibujos animados a WebAssembly ”, Lin Clark

(rb, ra, il)Explora más en

  • javascript
  • Navegadores
  • Asamblea web
  • Aplicaciones





Tal vez te puede interesar:

  1. ¿Deberían abrirse los enlaces en ventanas nuevas?
  2. 24 excelentes tutoriales de AJAX
  3. 70 técnicas nuevas y útiles de AJAX y JavaScript
  4. Más de 45 excelentes recursos y repositorios de fragmentos de código

Cómo utilizamos WebAssembly para acelerar nuestra aplicación web hasta 20 veces (estudio de caso)

Cómo utilizamos WebAssembly para acelerar nuestra aplicación web hasta 20 veces (estudio de caso)

Índice Fondo fastq.bio: la implementación de

programar

es

https://pseint.es/static/images/programar-como-utilizamos-webassembly-para-acelerar-nuestra-aplicacion-web-hasta-20-veces-estudio-de-caso-977-0.jpg

2024-04-04

 

Cómo utilizamos WebAssembly para acelerar nuestra aplicación web hasta 20 veces (estudio de caso)
Cómo utilizamos WebAssembly para acelerar nuestra aplicación web hasta 20 veces (estudio de caso)

Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

 

 

Top 20