From b8489ff6c194c79ed7666d4243d20e2b9b039e97 Mon Sep 17 00:00:00 2001 From: "Brian.Orwe" Date: Fri, 18 Aug 2023 17:34:27 +0300 Subject: [PATCH] Update README.md --- README.md | 25 +++++++++-------- default_cfg/perf.lua | 48 +++++++++++++++++++++++++++++++++ imgs/1690628636000.png | Bin 16962 -> 0 bytes imgs/perf.png | Bin 0 -> 45210 bytes wasm/perf.zig | 59 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 120 insertions(+), 12 deletions(-) delete mode 100644 imgs/1690628636000.png create mode 100644 imgs/perf.png diff --git a/README.md b/README.md index 37a2743..194c9e8 100644 --- a/README.md +++ b/README.md @@ -6,22 +6,25 @@ Write a library to interface between Lua, and wasm, for enabling communication b ## Performance: -There is a poor mans performance test implementation, that imitates [Bram's implementation](https://github.com/vim/vim/blob/master/README_VIM9.md) of just summing a number inside a for loop, more will be done later, but as it appears now, wasm is faster than luajit atleast on my Windows 10 machine as you can see from the results: -![1690628636000](./imgs/1690628636000.png) +- The first test is a poor mans performance test implementation, that imitates [Bram's implementation](https://github.com/vim/vim/blob/master/README_VIM9.md) of just summing a number inside a for loop, wasm is faster by **99%**, due to compiler optimizations of the language om this case it is zig, this mostly shows the compilation optmization benefits that compiling to wasm could bring to the table vs JIT with LuaJIT. -Wasm version is atleast 30% faster than luajit/neovim version, if you compile for full optimisation for example in rust, you can get even 90% boost as seen in the image. -To run this test simply run the bellow: +- The second one is a test where we try get the prime numbers between 0-10000, and count the number of times it could be achieved within 5 seconds, there is no constants, so even the wasm compiled shouldn't optimize the away almost all the operations like it did in the first test. Here wasm was **99%** faster than Luajit. I didn't want to optmize the algorithm for each specific language, instead used basic structures, and avoid bitwise manipulation or stack pre allocation even on the zig/wasm side. -```sh -cargo make perf -``` +- This image shows the tests:![1690628636000](./imgs/perf.png) +- To run this test simply run the bellow: + + ```sh + cargo make perf + ``` + + Requires: -Requires: + - `cargo-make` which can be installed by `cargo install cargo-make` . + - `zig` to be in system path, can be installed from [Download ⚡ Zig Programming Language (ziglang.org)](https://ziglang.org/download/) -- `cargo-make` which can be installed by `cargo install cargo-make` . -- `zig` to be in system path, can be installed from [Download ⚡ Zig Programming Language (ziglang.org)](https://ziglang.org/download/) +- Overall Wasm should be faster than luajit on average, without trying any fancy optimization techniques, for a wider range of luajit vs wasm comparisons one can check [here](https://programming-language-benchmarks.vercel.app/wasm-vs-lua) -**NOTE: Current test only runs on Windows 10. That's the machine I have.** +**NOTE: Current perf test results shown are from a Windows 10 PC. That's the machine I have.** ## READING: diff --git a/default_cfg/perf.lua b/default_cfg/perf.lua index 2543638..0e25795 100644 --- a/default_cfg/perf.lua +++ b/default_cfg/perf.lua @@ -25,3 +25,51 @@ end print("Lua For Loop takes: "..lua_for_loop().."s\n"); print("Wasm Time From Nvim For Loop takes: "..wasm_for_loop().."s\n"); + + +function lua_primes(size) + local factos = {} + local primes = {2,} + + local i = 3; + while i<= size do + local is_prime = true + -- check if is a factor + for _, val in pairs(factos) do + if val == i then + is_prime = false + break + end + end + + if is_prime == true then + table.insert(primes,i) + --fill factos + local j =3 + while j*i < size do + table.insert(factos,j*i) + j = j+2 + end + end + i=i+2 + end + + -- print("LUA PRIMES: "..#primes) +end + +function test_prime() + print(" \n") + print("Starting to get number of primes between 0-1000") + print("Over a period of 5 seconds in both wasm and lua...") + local times_lua = 0 + local start = vim.fn.reltime(); + while(vim.fn.reltimefloat(vim.fn.reltime(start)) < 5) do + lua_primes(10000) + times_lua = times_lua + 1 + end + print("-LUA has done it "..times_lua.." times") + local times_wasm = wasm.perf.wasm_primes(10000) + print("-WASM has done it "..times_wasm.." times\n") +end + +test_prime() diff --git a/imgs/1690628636000.png b/imgs/1690628636000.png deleted file mode 100644 index 46968a9e382667331faadde92d0467e8a52ac9f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16962 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 W4+sKzI?uPR!%)}kX4MV1$o~R;=Npy) literal 0 HcmV?d00001 diff --git a/wasm/perf.zig b/wasm/perf.zig index b763679..8956cee 100644 --- a/wasm/perf.zig +++ b/wasm/perf.zig @@ -5,7 +5,8 @@ const json = std.json; extern "host" fn get_id() u32; extern "host" fn set_value(id: u32, loc: u32, size: u32) void; extern "host" fn get_addr(ptr: *u8) u32; -extern "host" fn nvim_create_augroup(id: u32) i64; +extern "host" fn get_value_size(id: u32) u32; +extern "host" fn get_value_addr(id: u32) [*]u8; var aloc: std.mem.Allocator = std.heap.page_allocator; @@ -32,6 +33,7 @@ export fn functionality() u32 { var funcs = ArrayList(Functionality).init(aloc); defer funcs.deinit(); funcs.append(CreateFunctionality("for_loop", "void", "void")) catch unreachable; + funcs.append(CreateFunctionality("wasm_primes", "u32", "u32")) catch unreachable; var jsoned = ArrayList(u8).init(aloc); std.json.stringify(funcs.items, .{}, jsoned.writer()) catch undefined; @@ -55,3 +57,58 @@ export fn for_loop() void { var writer = std.io.getStdOut().writer(); writer.print("Wasm Time from inside function For Loop takes: {d}\n", .{diff}) catch undefined; } + +fn get_primes(size: u32) void { + var factos = ArrayList(u32).init(aloc); + defer factos.deinit(); + var primes = ArrayList(u32).init(aloc); + primes.append(2) catch unreachable; + defer primes.deinit(); + + var i: u32 = 3; + while (i < size) { + var is_prime = true; + // check if i is a factor + for (factos.items) |f| { + if (f == i) { + is_prime = false; + break; + } + } + + if (is_prime == true) { + primes.append(i) catch unreachable; + var j: u32 = 3; + while (j * i < size) { + factos.append(j * i) catch unreachable; + j += 2; + } + } + i += 2; + } + + // std.io.getStdOut().writer().print("WASM PRIMES: {d}\n", .{primes.items.len}) catch unreachable; +} + +export fn wasm_primes(id: u32) u32 { + const in_size = get_value_size(id); + var inArray = ArrayList(u8).init(aloc); + defer inArray.deinit(); + inArray.capacity = in_size; + inArray.items = get_value_addr(id)[0..in_size]; + + const size = json.parseFromSlice(u32, aloc, inArray.items, .{}) catch unreachable; + + var times: u32 = 0; + const start = std.time.milliTimestamp(); + while (std.time.milliTimestamp() - start < 5000) { + get_primes(size.value); + times += 1; + } + + const return_id = get_id(); + var results = ArrayList(u8).init(aloc); + json.stringify(times, .{}, results.writer()) catch unreachable; + set_value(return_id, get_addr(&results.items[0]), results.items.len); + return return_id; +}