Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
perf, memory: Improve performance and memory use for large datasets #5927
base: main
Are you sure you want to change the base?
perf, memory: Improve performance and memory use for large datasets #5927
Changes from 5 commits
73a6b1e
0cc9f19
3ff5df9
a964f41
24710f8
0769660
3620a00
aa518e9
fdc1771
9cf94c1
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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.
In the core
createRow
function, we still call thesefeature.createRow
functions if they exist, passing them the row and table instance. That should prevent breaking changes for existing custom features, but we may want to recommend custom features to take the same approach (i.e. extend the prototype). @KevinVandy what do you think about this?I haven't thought all the details through but something like retaining a
createRow
function in each feature, and in the corecreateRow
function both calling thefeature.createRow
function with the row and table instances (to prevent breaking changes for existing custom features), and also merging its prototype onto the corecreateRow
prototype.That way we could also retain the
createRow
functions in the core features, (just move the methods onto the prototype), and wouldn't need thegetRowProto
andObject.assign()
approach I think.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.
+1 to generally recommending people use the same approach for implementing custom features. I considered making things more explicit by adding methods like
initRowProto()
toTableFeature
interface, but decided against it for simplicity's sake, plus this is more of an internal implementation detail than a public API.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 kind of pattern will be useful to think about in the alpha branch though
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.
At one point, we had removed most usages of
Object.assign
in favor of direct assignment as a performance improvement at scale. Wonder if that's still applicable to consider here.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.
It wouldn't be an issue here since it's only called once per table anyway. Your question would apply more to
createRow()
inrow.ts
since we call it once per row there, but AFAIK, there are no known performance issues aroundObject.assign()
. There have been some many years ago when it was just introduced and browser support was fresh (plus there were polyfills), but that hasn't been the case in quite some time.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.
@KevinVandy beat me to it. I like the idea but am not a big fan of typing the prototype as CoreRow which is not strictly accurate, (and requires us to create these dummy values to keep typescript happy).
@mleibman-db did you try making the createRow function into a constructor function, adding the methods directly to the prototype? I haven't tried it myself but intuitively it feels like it should work. Would need to always call createRow with the new keyword I think.
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.
Typing the row proto as
CoreRow
is actually very useful since it provides type safety and makes sure the methods only access defined props there. The use of default unused values there doesn't strike me as concerning, but we could try to replace them with some purely TypeScript type annotations, though IMHO that would be more hacky.I'm not sure I understand what you're proposing. Could you elaborate?
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.
It's the wrong type though, isn't it? The prototype shouldn't have the instance properties on it.
I am imagining something approximately like the below. I haven't tried but think it should work, happy to be corrected. The naming would be a bit weird though.
createRow
should probably become justRow
, but that would be a breaking change - not sure what to do about that.elsewhere:
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.
Anywhere where we are thinking that an alternative would be cleaner, but it's a breaking change, can be reserved for a v9 pr. So far this PR looks mostly good. We don't have to assign dummy vars to the prototype just to satisfy TypeScript. A cast could be acceptable there.
If the Object.assign only gets called once, that is negligible and something we don't need to worry about. Direct assignment was a performance improvement in this pr that sped up rendering when creating 10k+ rows. This PR is solving the memory side of that same issue. In conclusion, I'm not worried about this after you explained 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.
But I think you can merge the
feature.createRow
prototypes into the prototype of the object returned by the corecreateRow
function at runtime, whennew createRow()
is called. In the same loop where we currently callfeature.createRow
in the corecreateRow()
function body. I haven't tested this though. In this case the prototype's methods would be created at module level on each of the features'createRow
functions.Personally I am not opposed to using a class if it makes typing easier.
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.
(and just for anyone reading this ... the code snippet in this comment should be using
function createRow() {}
, not an arrow function!)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 was actually agreeing with you that since it's not called many times, it wouldn't be likely to cause issues. I was just trying to explain the likely cause of perf issues - not due to
Object.assign()
itself, but rather the fact that it it often called like this:If it's used this way in a loop with many thousands of iterations, you can run into perf issues due to garbage collection.
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.
Done.