nim-lang / nightlies

Separate repository to trigger installer builds.
MIT License
44 stars 14 forks source link

jsgen return value performance #57

Closed JoeKays closed 3 years ago

JoeKays commented 3 years ago

Hi,

I'm just took nim for a spin for the first time and noticed that the way it handles return values in generated javascript seems to cause a massive performance hit (at least inside nimCopy proc).

For this test I created a vector class:

type vec = object
    x, y: float

and overloaded the + operator (nim fixes js's lack, that's so awesome!):

proc `+` (a, b: vec): vec {.noinit.} =
    result.x = a.x + b.x
    result.y = a.y + b.y

When I run a naive performance test like this:

let now = window.performance.now()/1000
var tmp = vec(x:0.0, y:0.0)
let vec1 = vec(x:1.0, y:2.0)
let vec2 = vec(x:3.0, y:4.0)
for i in 1..10_000_000:
    tmp = tmp + vec1 + vec2
echo "tmp:", tmp, "time:", window.performance.now()/1000-now, "s"

I have ~10-100x higher runtime than necessary. By simple changing the generated nimCopy function's return handling I achieve near plain-js performance: Instead of doing:

var result = null; result = ...; return result;

simply returning everywhere without the extra variable is way more performant:

return ...;

Now I wonder if this is a problem with the generated js return in general or only in nimCopy proc?

Joe

JoeKays commented 3 years ago

My bad, wrong repository :(

Can someone move this?

Araq commented 3 years ago

I'll reply here anyway: The performance problem of nimCopy is known and will dispappear once the JS codegen understands that it too can benefit from --gc:orc... PRs are most welcome, I can guide you through Nim's internals. Maybe join our Discord channel.

JoeKays commented 3 years ago

Thank you for the quick reply! I'll try to fix it and create a PR. In the meantime I will leave this open...

JoeKays commented 3 years ago

Closing, this was a mistake, the performance issue has nothing to do with the return value.