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

perf(pg): avoid useless spread #3379

Merged
merged 2 commits into from
Feb 11, 2025
Merged

perf(pg): avoid useless spread #3379

merged 2 commits into from
Feb 11, 2025

Conversation

cesco69
Copy link
Contributor

@cesco69 cesco69 commented Feb 11, 2025

Just a micro-optimization for avoid useless spread operator on object

@brianc
Copy link
Owner

brianc commented Feb 11, 2025

👍 🙇

@brianc brianc merged commit 5f6a6e6 into brianc:master Feb 11, 2025
5 checks passed
@cesco69 cesco69 deleted the patch-5 branch February 11, 2025 16:50
@charmander
Copy link
Collaborator

The spread was intentional. Did you benchmark this?

@cesco69
Copy link
Contributor Author

cesco69 commented Feb 12, 2025

The spread was intentional. Did you benchmark this?

Yep! but the difference is negligible. In multiple run, sometimes wins the spread version, but I think is just because we talking about a very little difference. Honestly I have read the comment but not fully undestand why the spread should be improve the performance, it create a new object!

Maybe @koenfaro90 can help us

@charmander do you have noticed some slow down in the latest version?

@koenfaro90
Copy link
Contributor

@cesco69 @charmander @brianc

Constructing using spread itself is not any faster or slower. But USING objects generated with a 'fixed' shape is MUCH MUCH faster than using objects which are dynamically shaped. So if you start with an object with 0 properties and continually add properties the shape of that object will be complex - versus assigning all of them at initialization which leads to a simple shape.

Some more background at

https://v8.dev/blog/fast-properties
https://mathiasbynens.be/notes/shapes-ics

The patch I made ensured that objects have a 'simple' shape. This results in significant (IIRC 10-100x) speed-up when doing something like JSON.stringify on the returned objects - considering the objects contain a significant amount of columns.

@cesco69
Copy link
Contributor Author

cesco69 commented Feb 12, 2025

@cesco69 @charmander @brianc

Constructing using spread itself is not any faster or slower. But USING objects generated with a 'fixed' shape is MUCH MUCH faster than using objects which are dynamically shaped. So if you start with an object with 0 properties and continually add properties the shape of that object will be complex - versus assigning all of them at initialization which leads to a simple shape.

Some more background at

https://v8.dev/blog/fast-properties https://mathiasbynens.be/notes/shapes-ics

The patch I made ensured that objects have a 'simple' shape. This results in significant (IIRC 10-100x) speed-up when doing something like JSON.stringify on the returned objects - considering the objects contain a significant amount of columns.

Thanks for the detailed response! In your opinion my changes https://github.com/brianc/node-postgres/pull/3379/files can be a problem?

@koenfaro90
Copy link
Contributor

koenfaro90 commented Feb 12, 2025

@cesco69 @charmander @brianc

Yes; this removes the performance fix as now you are using a dynamically shaped object to clone from, resulting in a major performance regression for any application using this library. So in my opinion this should be reverted before the next release. Perhaps we should add some tests regarding the performance of using the objects resulting from PG?

I have a repo running some tests:

https://github.com/koenfaro90/node-postgres-bench/tree/master

@cesco69
Copy link
Contributor Author

cesco69 commented Feb 12, 2025

Yes; this removes the performance fix as now you are using a dynamically shaped object to clone from, resulting in a major performance regression for any application using this library. So in my opinion this should be reverted before the next release. Perhaps we should add some tests regarding the performance of using the objects resulting from PG? I don't have mine handy anymore right now.

ok, I have understood, thanks. Sorry for my mistake!

With this PR #3382 revert both in pg and pg-native

brianc pushed a commit that referenced this pull request Feb 13, 2025
* Update result.js

* Update build-result.js

* fix: lint

* fix: lint
@jorrit
Copy link

jorrit commented Feb 13, 2025

Perhaps add some comments to explain the reason why these spreads are necessary.

@cesco69
Copy link
Contributor Author

cesco69 commented Feb 13, 2025

I have a repo running some tests:

https://github.com/koenfaro90/node-postgres-bench/tree/master

@koenfaro90 version 8.13.2 (the version with my PR) has introduced slowness compared to 8.13.1

< 8.13.1; 30995ms
< 8.13.2; 31712ms
< 8.13.3; 30551ms

Side note, this project is gold https://github.com/koenfaro90/node-postgres-bench/tree/master and should be part of this repo!

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.

5 participants