diff options
author | metagn <metagngn@gmail.com> | 2024-09-08 23:11:12 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-08 22:11:12 +0200 |
commit | ebcfd96ae1ba10cdf31cb3167a12d4d76d75a8c9 (patch) | |
tree | 536cedc8a81414d8b3bf65458f1df3475fe039fb | |
parent | cd22560af5f13a7c024b97e2f3de2b1fe2439eb3 (diff) | |
download | Nim-ebcfd96ae1ba10cdf31cb3167a12d4d76d75a8c9.tar.gz |
improve compiler performance on dot fields after #24005 (#24074)
I noticed after #24005 the auto-reported boot time in PRs increased from around 8 seconds to 8.8 seconds, but I wasn't sure what could cause a performance problem that made the compiler itself compile slower, most of the changes were related to `static` which the compiler code doesn't use too often. So I figured it was unrelated. However there is still a performance problem with the changes to `tryReadingGenericParam`. If an expression like `a.b` doesn't match any of the default dot field behavior (for example, is actually a call `b(a)`), the compiler does a final check to see if `b` is a generic parameter of `a`. Since #24005, if the type of `a` is not `tyGenericInst` or an old concept type, the compiler does a full traversal of the type of `a` to see if it contains a generic type, only then checking for `c.inGenericContext > 0` to not return `nil`. This happens on *every* dot call. Instead, we now check for `c.inGenericContext > 0` first, only then checking if it contains a generic type, saving performance by virtue of `c.inGenericContext > 0` being both cheap and less commonly true. The `containsGenericType` could also be swapped out for more generic type kind checks, but I think this is incorrect even if it might pass CI.
-rw-r--r-- | compiler/semexprs.nim | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 737a846c0..081eb6847 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1504,12 +1504,9 @@ proc tryReadingGenericParam(c: PContext, n: PNode, i: PIdent, t: PType): PNode = result.typ = makeTypeFromExpr(c, copyTree(result)) else: result = nil - elif t.containsGenericType: - if c.inGenericContext > 0: - result = semGenericStmt(c, n) - result.typ = makeTypeFromExpr(c, copyTree(result)) - else: - result = nil + elif c.inGenericContext > 0 and t.containsGenericType: + result = semGenericStmt(c, n) + result.typ = makeTypeFromExpr(c, copyTree(result)) else: result = nil |