Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
Borwe committed Aug 18, 2023
1 parent eac1ad8 commit b8489ff
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 12 deletions.
25 changes: 14 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
48 changes: 48 additions & 0 deletions default_cfg/perf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Binary file removed imgs/1690628636000.png
Binary file not shown.
Binary file added imgs/perf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 58 additions & 1 deletion wasm/perf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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;
}

0 comments on commit b8489ff

Please sign in to comment.