Closed Kiddinglife closed 1 year ago
It's an interesting question. I wrote a simple test program to measure the throughput of JSON parsing, and compiled it to both wasm and native:
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __EMSCRIPTEN__
#include "emscripten.h"
#endif
#include "yyjson.h"
double get_time(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec / 1000000.0;
}
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_KEEPALIVE
#endif
int run() {
const char *path = "twitter.json";
const int iter = 30;
const int repeat_per_iter = 100;
#define err(msg) { if (fd) fclose(fd); if (dat) free(dat); printf(msg); return 1; }
char *dat = NULL;
FILE *fd = fopen(path, "rb");
if (!fd) err("failed to open file");
fseek(fd, 0, SEEK_END);
size_t len = ftell(fd);
fseek(fd, 0, SEEK_SET);
if (len == 0) err("empty file");
dat = malloc(len);
if (!dat) err("failed to alloc memory");
if (fread(dat, 1, len, fd) != len) err("failed to read file");
fclose(fd);
fd = NULL;
for(int i = 0; i < iter; i++) {
double t1 = get_time();
for(int j = 0; j < repeat_per_iter; j++) {
yyjson_doc *doc = yyjson_read(dat, len, 0);
if (!doc) err("failed to parse json");
yyjson_doc_free(doc);
}
double t2 = get_time();
double speed = len * repeat_per_iter / (t2 - t1) / 1024.0 / 1024 / 1024;
printf("iter %d: %f ms (%.2fGB/s)\n", i, (t2 - t1) * 1000, speed);
}
free(dat);
return 0;
}
#ifndef __EMSCRIPTEN__
int main() { return run(); }
#endif
emcc -O3 -s WASM=1 -s EXPORTED_RUNTIME_METHODS='["cwrap"]' yyjson.c test.c --embed-file twitter.json
clang -O3 yyjson.c test.c -o test
Chrome: 1.40 GB/s, Native: 3.53 GB/s (M1 Mac) Chrome: 0.62 GB/s, Native: 1.57 GB/s (Old Mac, 7th gen Intel Core)
I found a more extensive performance test report: https://00f.net/2023/01/04/webassembly-benchmark-2023/ which mentions that
When using the fastest runtime, WebAssembly was only about 2.32 times slower (median) than native code with architecture-specific optimizations
It seems that the performance of yyjson on wasm is not much different from other libraries.
Does it still keep the super high performance considering that there are lots of tricks used in yyjson ? Thx.