Retour d’expérience sur l’utilisation d’un projet C++ en JavaScript (ASM.js, WASM)

Utilisation d'un projet C++ en JavaScript (ASM.js, WASM)

Jerome Martinez

Si vous avez une remarque ou un avis concernant cet article, un espace de discussion vous est proposé sur le forum. Commentez ♪

- Titre : Retour d’expérience sur l’utilisation d’un projet C++ en JavaScript (ASM.js, WASM)

- Auteur : Jerome Martinez

- Parution : 13 décembre 2018

- Public visé :

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2018 Jerome Martinez. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Présentation sommaire du projet MediaInfo

- II. Retour d’expérience sur l’exploitation de MediaInfo

- III. Quelques liens

I - Présentation sommaire du projet MediaInfo

Nous développons principalement un logiciel d'analyse des informations techniques et de métadonnées fichiers multimédias appelé MediaInfo.

Celui-ci est codé en C++ et donc nécessite une compilation par plateforme (Windows, Mac, Linux…) pour nous, et l'utilisateur potentiel doit télécharger, puis installer (ou décompresser), actions faciles pour ceux qui connaissent l'informatique, mais compliquées pour des utilisateurs non intéressés par la technique et/ou « butineurs » (si trop compliquées, ils passent à autre chose). Les « Stores » commencent à être connus et sont faciles, nous sommes sur le Mac App Store et sur le Windows Store, mais ce dernier n'est pas bien mis en avant et donc peu utilisé bien que Windows soit la plateforme majoritaire de nos utilisateurs.
Nous avons donc été curieux de voir si une version directement en ligne, sans installation, pouvait amener de nouveaux utilisateurs.

II - Retour d’expérience sur l’exploitation de MediaInfo

Lorsque nous avons découvert Emscripten en 2013, nous avons fait « wôw » sur l'idée : pouvoir utiliser MediaInfo en ligne sans avoir besoin de recoder tout en JS, super, pas de temps perdu à changer de langage de programmation. Nous avons donc fait une première tentative de portage du code C++ vers ASM.js. Après plusieurs jours à adapter l'interface aux contraintes de ASM.js (on ne peut pas ouvrir le fichier directement dans le logiciel, il faut utiliser l'API JS pour lire les données du fichier, puis passer les octets au logiciel), nous avons pris peur sur le résultat en termes de taille du code JS à envoyer au client (plus de dix Mo), de la mémoire vive nécessaire (plus de 1 Go), et de la lenteur (plusieurs secondes à la place de quelques centaines de millisecondes). Inutilisable. Nous avons abandonné l'idée.

Cette année, nous avons trouvé un site utilisant sa version de MediaInfo en ligne (tout à fait légal, nous publions en open source) ; ha… Mais c'est que ça marche plutôt bien ! Code JS pas trop gros (un Mo), mémoire vive nécessaire contenue (~100 Mo de plus dans le navigateur), et plutôt rapide (~500 ms). Et en plus l'auteur met le code source en ligne, donc on a pu voir comment il avait fait.
On ne voulait pas dépenser de l'argent (le temps d'un développeur est de l'argent pour son employeur) pour rien, mais là nous avions la preuve que ça fonctionnait, donc on a de nouveau tenté. Le code utilisé ne nous convenait pas (API de MediaInfo pas équivalente à l'API des autres codes glues (OpenGL Utility Library) pour d'autres langages, possibilité de faire plus simple, pas de support de fichier de plus de quatre Go du fait de limites à 32 bits des entiers JS, de la façon dont c'était codé, nous voulions aussi garder l'objet MediaInfo pour faire quelques manipulations du résultat après analyse…), nous avons donc décidé de ne pas reprendre le code de cet auteur, mais de faire notre propre « glue » entre MediaInfo pour Emscripten et le navigateur, avec en plus une intégration avec notre site web pour pouvoir utiliser MediaBin, qui permet de partager les rapports MediaInfo. Cela a pris quelques jours de développement. Nous avons aussi intégré un exemple dans notre liste de « glue » pour les langages non C++.

Les difficultés rencontrées sont surtout sur la partie asynchrone de JS, alors que MediaInfo attend plutôt du synchrone, il a fallu faire un changement de paradigme dans l'API de notre logiciel. Heureusement pour nous, nous avions eu précédemment une demande ressemblant à un besoin d'appel asynchrone et donc les évolutions à faire ont été mineures.
Une autre difficulté avec JS est que les entiers sont limités à 32 bits, donc il a fallu contourner cette limite quand la taille du fichier, donnée dont nous avons besoin, ne rentre pas dans 32 bits.
Il y avait aussi un problème sur l'impossibilité d'utiliser un même nom de fonction pour une commande acceptant plusieurs types de variables, mais nous avions déjà eu ce problème avec notre « glue » C, donc nous avons utilisé le même principe que notre « glue » C.
Et voilà, ce développement et une page web dédiée nous donne MediaInfoOnline, une version de MediaInfo en ligne utilisée même sur iPad, sans effort pour l'utilisateur qui a juste à faire un glisser/déposer du fichier à analyser.

Une fois la version ASM.js faite, nous avons vu que WASM était de plus en plus supporté par les navigateurs, et il y a une promesse de plus de rapidité et comme le coût de développent pour WASM est faible (une option dans Emscripten, un peu d'adaptation de notre site web pour gérer les deux versions, la version ASM.js devant rester pour les navigateurs plus anciens), nous avons testé. Le gain est relativement faible (quelques centaines de ko de moins pour la taille du code transféré à l'utilisateur, un peu plus de rapidité), mais le coût l'est aussi donc ce fut pertinent de notre point de vue.

III - Quelques liens

- Le script de compilation.

- Le code glue entre MediaInfo C++ et JS.

- Le code JS pour lire le fichier et passer le contenu à MediaInfo.

- Le package autonome pour tester chez soi.

- L'utilisation en ligne MediaInfoOnline.