-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Core: Fix performance issue when combining tasks by partition #9629
Conversation
return data; | ||
} | ||
|
||
private static Object toInternalValue(Object value) { |
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.
Moved from set
to avoid calling that public method in the new constructor.
Types.StructType groupingKeyType, | ||
StructLike partition) { | ||
|
||
PartitionData groupingKey = new PartitionData(groupingKeyType); |
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.
This line was causing the issue.
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.
Just for my understanding, the repeated calling of this constructor was expensive because the repeated data array initialization (and possibly the determining of the partitionType via AvroSchemaUtil.convert
)? And now we avoid repeatedly performing those computations by having a PartitionData
be initialized with a "template" just once for all tasks and then replace the actual data in PartitionData#copyFor
?
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.
Yep, correct, @amogh-jahagirdar.
@@ -171,6 +169,10 @@ public PartitionData copy() { | |||
return new PartitionData(this); | |||
} | |||
|
|||
public PartitionData copyFor(StructLike partition) { |
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.
An alternative to this is to create a new StructLike
class simply backed by an array and populate it in the table scan utility. I went with this approach because we do a similar trick in other places.
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.
I find this API to be a bit awkward. I'd rather have a more straightforward two-step process to copy the key without copying values (like emptyCopy()
) and then fill that with values. Otherwise "copy" doesn't really describe this action, which copies behavior but not data.
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.
I am not entirely happy too. I followed what we did in other places like StructLikeProjection.
Do we really need PartitionData here? What if we simply create a container struct backed by an array and use it?
My worry with emptyCopy() is that the result object is in a weird state, I am not sure it is actually better than copyFor().
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.
We only need to a serializable projection used as a grouping key. Not more.
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.
An alternative to this is to create a new StructLike class simply backed by an array and populate it in the table scan utility
There's already org.apache.iceberg.io.StructCopy
class, maybe we can leverage that.
b1a90b0
to
a52019e
Compare
Thanks for the fix, @aokolnychyi! I think it's important to get this into 1.5 so I merged this. The method name should be okay. |
This PR fixes a substantial performance issue in combining tasks by partition for SPJ, which was caused by repetitive creation of
PartitionData
, which triggered expensive initialization.Before
After