Skip to content

Assignment in result variables generates genericResets #6501

@edubart

Description

@edubart

Assignment to result variables generate calls to genericReset becoming ~5x slower than raw field assignment, the test case:

import times

type Foo = object
  val: int
  s: seq[int]

proc newFoo(): Foo =
  result.val = 1

proc boo(): Foo =
  result = newFoo()

proc boo2(): Foo =
  let a = newFoo()
  result.s = a.s
  result.val = a.val

proc main() =
  block:
    let start = epochTime()
    for i in 0..<1000000000:
      let a = boo()
    echo "boo ", epochTime() - start

  block:
    let start = epochTime()
    for i in 0..<1000000000:
      let a = boo2()
    echo "boo2 ", epochTime() - start

main()

Outputs:

elapsed 14.58154105735779
elapsed 3.642938910873413

As you can see boo2 that assigns each field separately is faster than boo. The problem is that boo generate genericReset calls which causes the slow down:

boo generates

N_NIMCALL(void, boo_9aSl0jzccntfjPB4osXEnHA)(tyObject_Foo_Bsmztv1sSxNkRrfi5afFAg* Result) {
	genericReset((void*)Result, (&NTI_Bsmztv1sSxNkRrfi5afFAg_));
	newFoo_9aSl0jzccntfjPB4osXEnHA_2(Result);
}

boo2 generates:

N_NIMCALL(void, boo2_9aSl0jzccntfjPB4osXEnHA_3)(tyObject_Foo_Bsmztv1sSxNkRrfi5afFAg* Result) {
	tyObject_Foo_Bsmztv1sSxNkRrfi5afFAg a;
	memset((void*)(&a), 0, sizeof(a));
	memset((void*)(&a), 0, sizeof(a));
	newFoo_9aSl0jzccntfjPB4osXEnHA_2((&a));
	genericSeqAssign((&(*Result).s), a.s, (&NTI_qwqHTkRvwhrRyENtudHQ7g_));
	(*Result).val = a.val;
}

In the boo genericReset call could be avoided and a memset called just like boo2

Workaround: Assign each field separately.

Why is this a problem? As my code is full of returns via result assignment, it's also full of genericReset calls and when profiling genericReset does show on perf with high CPU usage.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions