Skip to content

Speed up bind functionality#2286

Merged
brianc merged 8 commits into
masterfrom
bmc/perf/faster-bind
Nov 4, 2020
Merged

Speed up bind functionality#2286
brianc merged 8 commits into
masterfrom
bmc/perf/faster-bind

Conversation

@brianc
Copy link
Copy Markdown
Owner

@brianc brianc commented Jul 17, 2020

Move from 3 loops (prepareValue, check for buffers, write param types, write param values) to a single loop. This speeds up the insert benchmark by around 100 queries per second. Performance improvement depends on number of parameters being bound.

Comment thread packages/pg-protocol/src/serializer.ts Outdated
Comment thread packages/pg-protocol/src/serializer.ts
@brianc brianc merged commit 07988f9 into master Nov 4, 2020
@brianc brianc deleted the bmc/perf/faster-bind branch November 4, 2020 14:27
private headerPosition: number = 0
constructor(private size = 256) {
this.buffer = Buffer.alloc(size)
this.buffer = Buffer.allocUnsafe(size)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious -- is changing to allocUnsafe here also contributes to performance improvements? The original PR comment doesn't mention anything about this change.
Also how certain we are that this doesn't cause any nasty side-effects of being, well, unsafe?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a link to the NodeJS documentation on Buffer.allocUnsafe().

I'm not an expert on Buffers, though the documentation's last sentenance says this can increase a performance (subtle) over Buffer.alloc().

Allocates a new Buffer of size bytes. If size is larger than buffer.constants.MAX_LENGTH or smaller than 0, ERR_INVALID_OPT_VALUE is thrown.

The underlying memory for Buffer instances created in this way is not initialized. The contents of the newly created Buffer are unknown and may contain sensitive data. Use Buffer.alloc() instead to initialize Buffer instances with zeroes.

[...]

Use of this pre-allocated internal memory pool is a key difference between calling Buffer.alloc(size, fill) vs. Buffer.allocUnsafe(size).fill(fill). Specifically, Buffer.alloc(size, fill) will never use the internal Buffer pool, while Buffer.allocUnsafe(size).fill(fill) will use the internal Buffer pool if size is less than or equal to half Buffer.poolSize. The difference is subtle but can be important when an application requires the additional performance that Buffer.allocUnsafe() provides.

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.

4 participants