Of course for plain compilers var parameters can be faster, because without smart optimizations result objects can be first allocated on the proc stack and then copied back to the caller variable. But I had the strong feeling that this optimization is generally done, so I never tried to avoiding result parameters. But my current observation is that a var parameter can be indeed faster, by 10 to 20 % in my test case. (I discovered that fact by tuning my chess engine, so it is a real life observation...)

import random, times

  Data = tuple
    a: array[16, int]
    age: int

proc p1(): Data =
  for i in mitems(result.a):
    i = random(7)
  result.age = random(7)

proc p2(res: var Data) =
  for i in mitems(res.a):
    i = random(7)
  res.age = random(7)

proc main =
  var h: Data
  var sum: int
  var t: float # cpuTime()
  t = cpuTime()
  for x in 0 .. 9999:
    h = p1()
    sum += h.age
  echo sum
  echo "p1: ", cpuTime() - t
  t = cpuTime()
  for x in 0 .. 9999:
    sum += h.age
  echo sum
  echo "p2: ", cpuTime() - t


# $ nim c -d:release  ups.nim
# ~/nim-chess2 $ ./ups
# 29915
# p1: 0.000519
# 60011
# p2: 0.00042

2017-04-18 15:05:38

Isn't tuple assignment by copy? That's probably the difference.

The optimization that Nim can make is to pass the function arguments by reference. Maybe try an example which passes the result of p1() directly to a function that takes a tuple. I suspect there would be no runtime difference in that case.

2017-04-18 17:21:30
I think for a fair comparison, you should zero out the memory in the var-parameter case, because that is done for the result variable and therefore would be the only fair comparison. But I think even then it would not explain the big difference.
2017-04-18 17:24:01
check this thread for discussion of var parameter https://forum.nim-lang.org/t/2754
2017-04-19 04:48:36