[JAVA] I also tried WebAssembly with Nim and C

http://qiita.com/akira_/items/55cf1f5911b14e265c6f Inspired by this article, I wrote the Nim version and the C version.

First result

The result of fibonacci (45)

environment

CPU: Intel Core i7-6700
RAM: 8GB x2
WebBrowser: Google Chrome 57.0.2987.98 (64-bit)
Language Elapsed
JavaScript 19.176
C Wasm 4.357
Rust Wasm 4.354
Nim Wasm 4.359

As for the result, please note that the result will change depending on the execution environment and each execution, just by pasting the one that was executed once.

Source code

# Nim
import os
import times
import strutils

proc fibonacci*(n: int64): int64 =
  if n <= 1'i64:
    1'i64
  else:
    fibonacci(n - 1'i64) + fibonacci(n - 2'i64)

proc main() =
  let args = commandLineparams()
  let n = args[0].parseInt()
  echo "fibonacci($#) = $#" % [$n, $fibonacci(n.int64)]

main()
// C
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

int64_t fibonacci(int64_t n) {
    if (n <= 1) {
        return 1;
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
}

int main(int argc, char** argv) {
    int n = atoi(argv[1]);
    printf("fibonacci(%d) = %" PRId64 "\n", n, fibonacci(n));
    return 0;
}

procedure

In the above article, it seems that it was built using the Docker image, but I used the one installed on Xubuntu on the VM using emsdk as the build environment.

I will omit the installation of compilers for various languages such as Rust and Nim.

Install Emscripten

http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html Download emsdk from, unzip it, and put it in your PATH.

After passing through PATH

$ emsdk update
$ emsdk install sdk-incoming-64bit
$ emsdk activate sdk-incoming-64bit

You can install and enable Emscripten itself with.

** Addendum ** After this

$ source emsdk-portable/emsdk_env.sh

I forgot to write what I need, so I will add it. I think it is good to write it in ~ / .profile etc. ** Addendum to here **

Regarding Emscripten, if it is sdk-incoming-64bit, it seems that the version flag of WebAssembly is properly 1.0. (As of March 14, 2017)

The caveat here is that not only Emscripten but also LLVM and Clang builds run, which is time consuming and consumes a lot of memory. Regarding memory, let's deal with it by preparing swap or preparing a large amount in the first place. (I dealt with it by allocating 10GB of memory to the VM)

All you have to do is run the compiler for your language.

# C
$ emcc -O3 -s WASM=1 -o fib-c.js fibonacci.c
# Rust
$ rustc -O --target=wasm32-unknown-emscripten -o fib-rust.js fibonacci.rs
# Nim
$ nim c -d:release -d:emscripten -o:fib-nim.js fibonacci.nim

For Nim, put the following nim.cfg in the same directory as the source.

@if emscripten:
  cc = clang
  clang.exe = "emcc"
  clang.linkerexe = "emcc"
  clang.options.linker = ""
  cpu = "i386"
  warning[GcMem]= off
  passC = "-s WASM=1"
  passL = "-s WASM=1"
@end

Impressions

--It's hard because the build of Emscripten is just heavy. --I feel like I want a choice of to Wasm compiler other than Emscripten ――For the time being, if you use WebAssembly, it will work fairly fast, probably because of the modern compiler. ――It takes time to compile using Emscripten for the first time, but after the second time, it compiles within 5 seconds at the longest. ――In particular, Nim has incremental compilation, and Rust is also under development, so even large programs will not be a problem.

Summary

I've benchmarked four languages: JavaScript, C, Rust, and Nim, but this article may be something I wrote to get Nim interested. Currently, it seems that the only language that WebAssembly can do is C / C ++ / Rust, but I would appreciate it if you could know that Nim can also do it. (I'm not sure if GC is working properly ...) Even with Nim, you can manipulate the DOM by using jsbind.

In particular, Nim has GC, so I think it's easier to write than C / C ++ / Rust, so I'd like it to be an option as a language that can be easily accelerated with WebAssembly.

Finally

We have created a site where you can benchmark WebAssembly so that you can easily try it with your browser.

https://snowlt23.github.io/wasm-bench-site/

It's a rough construction, but I hope you can feel the atmosphere by moving it for the time being.

As a caveat, I'm benchmarking from Wasm's perspective because it's a sloppy build, and that's why it's slower than JavaScript when N is small. We recommend about 40 <= N <= 46.


I'm a person who gets sick every time I write JavaScript, so I hope the day will come when it will become commonplace for various languages to work on the Web.

Recommended Posts

I also tried WebAssembly with Nim and C
I tried to get started with WebAssembly
I implemented Ruby with Ruby (and C) (I played with builtin)
I tried to read and output CSV with Outsystems
I started MySQL 5.7 with docker-compose and tried to connect
I tried to chew C # (reading and writing files)
I tried DI with Ruby
I tried UPSERT with PostgreSQL.
I tried BIND with Docker
I tried using JOOQ with Gradle
I tried morphological analysis with MeCab
Hello World with Docker and C
I tried to interact with Java
I tried UDP communication with Java
I tried GraphQL with Spring Boot
I tried Flyway with Spring Boot
I tried using WebAssembly Stadio (2018/4/17 version)
I tried to chew C # (polymorphism: polymorphism)
I tried customizing slim with Scaffold
Encrypt with Java and decrypt with C #
I tried printing a form with Spring MVC and JasperReports 3/3 (Spring MVC control)
I tried connecting to Oracle Autonomous Database 21c with JDBC Thin
I tried using Realm with Swift UI
I tried printing a form with Spring MVC and JasperReports 2/3 (form template creation)
Link Java and C ++ code with SWIG
I tried using Scalar DL with Docker
I tried using OnlineConverter with SpringBoot + JODConverter
I tried time-saving management learning with Studyplus.
I tried playing with BottomNavigationView a little ①
I tried using OpenCV with Java + Tomcat
I tried Lazy Initialization with Spring Boot 2.2.0
I tried to implement ModanShogi with Kinx
I tried to measure and compare the speed of GraalVM with JMH
I tried printing a form with Spring MVC and JasperReports Extra edition (Variables edition)
I tried printing a form with Spring MVC and JasperReports Extra edition (image edition)
I tried to convert JavaBean and XML with Jackson formatter XML in this era
I tried to verify AdoptOpenJDK 11 (11.0.2) with Docker image
I tried to make Basic authentication with Java
I compared classes and instances with worldly things
I tried to manage struts configuration with Coggle
I tried to manage login information with JMX
I tried to link grafana and postgres [docker-compose]
I tried writing CRUD with Rails + Vue + devise_token_auth
[Android] I quit SQLite and tried using Realm
I tried to chew C # (basic of encapsulation)
I made blackjack with Ruby (I tried using minitest)
I tried Eclipse MicroProfile OpenAPI with WildFly Swarm
I tried to link JavaFX and Spring Framework.
I tried to break a block with java (1)
I tried Getting Started with Gradle on Heroku
I tried to create a shopping site administrator function / screen with Java and Spring
I called YouTube video from DB with haml and tried to embed and display it
I tried Spring.
I tried tomcat
I tried youtubeDataApi.
I tried refactoring ①
I tried FizzBuzz.
I tried JHipster 5.1
I tried what I wanted to try with Stream softly.
I tried Mastodon's Toot and Streaming API in Java
I tried to implement file upload with Spring MVC