-
Notifications
You must be signed in to change notification settings - Fork 248
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
[compiler] Minor Requiredness Performance Enchancements #13991
Changes from 5 commits
d636db4
37985f3
14e668b
ccbd7f4
0b68065
03f13c8
330899b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -98,8 +98,11 @@ sealed abstract class BaseTypeWithRequiredness { | |
throw new AssertionError( | ||
s"children lengths differed ${children.length} ${newChildren.length}. ${children} ${newChildren} ${this}") | ||
} | ||
(children, newChildren).zipped.foreach { (r1, r2) => | ||
r1.unionFrom(r2) | ||
|
||
// foreach on zipped seqs is very slow as the implementation | ||
// doesn't know that the seqs are the same length. | ||
Comment on lines
+102
to
+103
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like this comment is out of place here. We use both of these patterns all over the codebase, and we shouldn't comment on their relative performance every time. Perhaps we should start a doc of these kinds of scala performance gotchas that we can refer to, and reevaluate with future scala version changes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for your feedback. A I don't think a doc would be that practical. Knowing me, I'd likely forget about it rather than consult it whenever I need to write simple code like a for-loop. |
||
for (i <- children.indices) { | ||
children(i).unionFrom(newChildren(i)) | ||
} | ||
} | ||
|
||
|
@@ -500,12 +503,12 @@ object RTable { | |
RTable(rowStruct.fields.map(f => f.name -> f.typ), globStruct.fields.map(f => f.name -> f.typ), key) | ||
} | ||
|
||
def fromTableStage(ec: ExecuteContext, s: TableStage): RTable = { | ||
def fromTableStage(ctx: ExecuteContext, s: TableStage): RTable = { | ||
def virtualTypeWithReq(ir: IR, inputs: Env[PType]): VirtualTypeWithReq = { | ||
import is.hail.expr.ir.Requiredness | ||
val ns = ir.noSharing | ||
val ns = ir.noSharing(ctx) | ||
val usesAndDefs = ComputeUsesAndDefs(ns, errorIfFreeVariables = false) | ||
val req = Requiredness.apply(ns, usesAndDefs, ec, inputs) | ||
val req = Requiredness.apply(ns, usesAndDefs, ctx, inputs) | ||
VirtualTypeWithReq(ir.typ, req.lookup(ns).asInstanceOf[TypeWithRequiredness]) | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand the use of this correctly?
For use as a boolean flag by IR passes. Each pass uses a different sentinel value to encode "true" (and anything else is false). As long as we maintain the global invariant that no two passes use the same sentinel value, this allows us to reuse this field across passes without ever having to initialize it at the start of a pass.
If this is accurate, could you add a comment here? The invariant is important: if anybody were to use this inconsistent with the above, it would break all other passes that use this field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly. Thanks for explaining it in a way I couldn't haha! I'll add the comment :)