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

Option to use pre-shaped result rows; fixes #3042 #3043

Merged
merged 6 commits into from
Aug 15, 2023

Conversation

koenfaro90
Copy link
Contributor

Adds option usePrebuiltEmptyResultObjects on the Query class; this results in generating pre-shaped result row objects instead of dynamically generated ones - massively increasing performance.

I had some difficulties running all tests; also not quite sure about style/backward compatibility demands, so let me know what needs adjusting before LGTM!

@koenfaro90
Copy link
Contributor Author

More info; #3042

@koenfaro90 koenfaro90 changed the title Option to use pre-shared result rows; fixes #3042 Option to use pre-shaped result rows; fixes #3042 Aug 11, 2023
@brianc
Copy link
Owner

brianc commented Aug 11, 2023

ohhhh that's super interesting & doesn't seem to introduce any unwanted weird behavior or dynamic class generation or memory leaks or anything. Exciting! I'll run this in CI & see what we can see. 😄

@koenfaro90
Copy link
Contributor Author

koenfaro90 commented Aug 11, 2023 via email

@brianc
Copy link
Owner

brianc commented Aug 11, 2023

All tests pass on all versions of node! FUN! I'm going to pull down your branch and run my horribly crude benchmark against it and current release & i'll report back.

@charmander
Copy link
Collaborator

I’d also be interested in how Object.fromEntries (+ Object.defineProperty polyfill for Node 10) benchmarks, since it avoids the (niche for pg, but uncomfortable) __proto__ hazard and is enabled by this change, but that’s for a future PR anyway!

@koenfaro90
Copy link
Contributor Author

I’d also be interested in how Object.fromEntries (+ Object.defineProperty polyfill for Node 10) benchmarks, since it avoids the (niche for pg, but uncomfortable) __proto__ hazard and is enabled by this change, but that’s for a future PR anyway!

You mean for constructing the initial cloneable-object? As that's called only once I would estimate that will be negligible in terms of performance regardless, but might indeed provide protection against a polluted prototype; however, that same risk was present in the current code, so indeed another PR for another day!

@koenfaro90
Copy link
Contributor Author

All tests pass on all versions of node! FUN! I'm going to pull down your branch and run my horribly crude benchmark against it and current release & I'll report back.

Does your benchmark include manipulating/using the result-rows? That's where the major gain would be, not so much in result construction I think, maybe a little. If you cannot quantify it, then I will write a small benchmark for that next week.

@koenfaro90
Copy link
Contributor Author

Seems the CI had a hickup, or is something actually failing now?

@koenfaro90
Copy link
Contributor Author

I wrote a little bench quickly; https://github.com/koenfaro90/node-postgres-bench/tree/master; there seems to be a tiny performance regression SOMEWHERE else, the actual operations seem faster, but somewhere else we seem to loose a little ms - I will investigate on Monday where the regression is caused.

8.11.2
< 8.11.2; 9952ms
pg-performance-pull
< pg-performance-pull; 10278ms
AccessCase { '8.11.2': 39.66, 'pg-performance-pull': 11.47 }
CloneUsingAssignCase { '8.11.2': 164.18, 'pg-performance-pull': 18.52 }
CloneUsingSpreadCase { '8.11.2': 179.6, 'pg-performance-pull': 3.2 }
KeysCase { '8.11.2': 17.12, 'pg-performance-pull': 0.83 }
ValuesCase { '8.11.2': 76.62, 'pg-performance-pull': 8.97 }

@brianc
Copy link
Owner

brianc commented Aug 12, 2023

Nice - I'm assuming on that output above a lower number is better? Should I be paying attention to the AccessCase and CloneUsingAssignCase etc or only the diff in numbers between 8.11.2 and pg-performance-pull?

It's always kinda cat and mouse game trying to benchmark the driver since postgres may take slightly longer or shorter to do a few queries, node might do a GC pause here or there, network, disk, etc all come into play. I'd recommend trying to run the bench like 10 times & seeing if you steadily see more or less performance from your branch, because in my experience it's not extremely steady numbers....but if actually accessing the row values by name is actually faster, and that speed up is somewhat linearly related to the number of rows returned, this is gonna be yuge!

@koenfaro90
Copy link
Contributor Author

koenfaro90 commented Aug 12, 2023 via email

@koenfaro90
Copy link
Contributor Author

Found the issue; needed to ensure that the clone-base record was properly shaped; now the new version is always considerably faster on all fronts (9600ms vs 10000ms for the suite).

@abenhamdine
Copy link
Contributor

amazing work @koenfaro90 !
by the way, if you are interesting in perf optimizations of this library, perhaps you would want to work on #2706, it's a POC that I can't dedicate time, but it would probably improve perfs significantly.

@koenfaro90
Copy link
Contributor Author

koenfaro90 commented Aug 14, 2023 via email

@brianc
Copy link
Owner

brianc commented Aug 15, 2023

Weirdly tests failed on a few versions of node...rerunning them. Looking forward to merging this!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants