Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #13739 #13742

Merged
merged 3 commits into from
Apr 7, 2020
Merged

fix #13739 #13742

merged 3 commits into from
Apr 7, 2020

Conversation

krux02
Copy link
Contributor

@krux02 krux02 commented Mar 24, 2020

fixes #13739

circumvents #13726 by not addressing #13417

@timotheecour
Copy link
Member

timotheecour commented Mar 25, 2020

arrays will deep copy here (pretty bad).
circumvents #13726

can some performance regression similar to #13726 happen as a result? if yes, I think we should fix it differently, using first class openarray (nim-lang/RFCs#88); I have a POC on that.

@krux02
Copy link
Contributor Author

krux02 commented Mar 25, 2020

can some performance regression similar to #13726 happen as a result? if yes, I think we should fix it differently, using first class openarray (nim-lang/RFCs#88); I have a POC on that.

Currently the input argument is someties copied into a temporary, and sometimes it is evaluated multiple times. The rules here are arbitrary. If you optimize for once case you make anther case slower. In this PR I kept the arbitrary rules. So I don't think a performance regression will happen. A deep copy only happens when there was a deep copy before. But now it doesn't create invalid code for arrays.

If first class openArray values will solve the problen still has to be proven. As far as I know, openarrays can only reference values. But for the temporary a move assignment is often necessary.

@timotheecour
Copy link
Member

timotheecour commented Mar 25, 2020

So I don't think a performance regression will happen. A deep copy only happens when there was a deep copy before

that's not what I'm observing
nim: 46c827b (devel): 4.000000000004e-06
nim2: 8368789 (your PR) 10.571572 (seconds)

when true: # D20200325T033719
  let n = 10_000_0000
  let m = 100
  var s = newSeq[int](n)
  for i in 0..<s.len: s[i] = i
  proc p2(): var seq[int] = s

  iterator ip1(v: openArray[int]): auto =
    yield v[0]
    yield v[1]
    yield v[^1]

  import times
  let t = cpuTime()
  for i in 0..<m:
    for x in ip1((discard; p2())):
      doAssert x != -1
  echo cpuTime() - t

how about this instead:

given this:

for x in myiter(body1): body2

when body1 is not a symbol, nim compiler transforms it into:

let tmp {.evalonce, gensym.} = body1
for x in myiter(tmp): body2

where {.evalonce.} is introduced in #13750; evalonce seems to provide a nicer alternative to evalOnceAs enabled by the recent feature introduced in #13508

this works with both lvalues and rvalues, doesn't make un-necessary copies, and enforces single evaluation.

@krux02
Copy link
Contributor Author

krux02 commented Apr 5, 2020

@Araq ready for review. Test failure unrelated. @timotheecour 's remark has been addressed.

@Araq Araq merged commit 37692ba into nim-lang:devel Apr 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

crash on openarray interator with argument in stmtListExpr
3 participants