nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.51k stars 1.46k forks source link

Support general NRVO #19357

Open arnetheduck opened 2 years ago

arnetheduck commented 2 years ago

In the current codegen, NRVO is artificially constrained to the use of the magic result variable - this leads to sub-optimal code generation in a number cases, both trivial and not, for example:

type X = object
  v: array[1024, int]

func f(): X =
  var tmp: X
  tmp.v[0] = 42
  tmp # an expensive `result = tmp` assignment is injected here

In the above code, there's no reason to not apply NRVO to tmp - the lack it leads to significant performance degradation, both in terms of memory usage (double that of tmp) and CPU (the hidden assignment takes cycles).

Using an named variable for the result is useful freedom to have in many cases, specially when working with algorithms and specifications where variables already have well-known names.

Araq commented 2 years ago

I have no objections, it would be a nice thing to have.

juancarlospaco commented 2 years ago

But I like the convention of using result as the thing you meant to return, in long functions it helps to keep track of returns when theres a lot of variables, some people even custom highlight result in the IDE...

arnetheduck commented 2 years ago

But I like the convention of using

you can continue liking it even when NRVO works like normal - it'll cover result also just like it does now. The difference is it will also cover the other 2 ways Nim has of returning things.

arnetheduck commented 2 years ago

in long functions it helps to keep track of returns when theres a lot of variables,

a tip though is that this is one of the cases you really want to avoid using it, and instead refactor the code to use a few intermediate local variables: a significant number of bugs we find in Nim come from assigning result multiple times or not at all in different if/case/try branches, and it's quite hard to find them (specially the non-assignments) - nim has really good expression support that helps you structure your code such that it becomes impossible to introduce this category of bugs.