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

chore(perf): Revert commit to bring back up to 20% perf #574

Merged
merged 2 commits into from
May 26, 2024

Conversation

JaoodxD
Copy link
Contributor

@JaoodxD JaoodxD commented May 22, 2024

As mentioned here #555 (comment) in one of the commits capacity optimization were made.
It saved 1 unit of storage per circular buffer but actually takes up to 20% of performance.
Link to commit which caused perf drop: 395e630

In one of the commits capacity optimization were made. It saved 1 unit of storage per circular buffer but actually takes up to 20% of performance.
Link to commit: piscinajs@395e630
Copy link
Member

Choose a reason for hiding this comment

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

Can we do benchmarks with payloads twice or three times its size?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean to push something bigger than integers or just more items?
If the second option then it's already done.
Results could be seen here #555 (comment) for twice the size, 64 times the size and 1024 times the size of single circular buffer.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, good call, sorry I missed that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No problem.
Btw in the last few days I tried to play with circular buffer size, tried to preallocate and reuse ring buffers with a pool and so on but nothing really brings benefits, only performance degradations.
It feels like FixedQueue was created by a dark magician who put an "unbeatable" spell on it. 😅

Copy link
Member

Choose a reason for hiding this comment

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

It is pretty well optimized. Liked the tradeoff of memory for more performance 👌

@metcoder95 metcoder95 changed the title Revert commit to bring back up to 20% perf chore(perf): Revert commit to bring back up to 20% perf May 22, 2024
@@ -65,7 +65,7 @@ test('remove not queued task should not lead to errors', async ({ equal }) => {
test('removing elements from intermediate CircularBuffer should not lead to issues', async ({ equal, same }) => {
const queue = new FixedQueue();

const batchSize = 2048;
const batchSize = 2047;
Copy link
Member

Choose a reason for hiding this comment

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

Does it fails with 2048?
In the worst case, it will pre-allocate another buffer, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In general it doesn't fail but it should match the batch size due to test's intensions.
The test may require additional clarification with comments.
The main goal was to check following scenario:

  1. We fill the queue with 3 full circular buffers amount of items.
  2. Empty the middle circular buffer.
  3. This should lead to the removal of the middle buffer from the queue:
  • Before emptying: tail buffer -> middle buffer -> head buffer.
  • After emptying: tail buffer -> head buffer.

My initial remove implementation didn't remove empty buffer so I wrote a test to fix it.

Copy link
Member

Choose a reason for hiding this comment

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

Nice, now is clear; maybe add that to the description of the test can help understand why are we doing that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Although I added the description I must admit that the test is actually insufficient/fragile due to lack of internal checks.
As you rightly noticed it doesn't and it wouldn't break even if the size of internal circular buffer will ever changes.
We potentialy could try to really check the amount of buffers with something like following, but this approach will definetly be broken when we ship "real" private fields in further major release.

const queue = new FixedQueue()

let buffer = queue.tail
let count = 0

while (buffer !== null) {
  count++
  buffer = buffer.next
}

console.log(`The queue has ${count} buffers`)

Copy link
Member

Choose a reason for hiding this comment

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

Overall, I'd not recommend to alter the internals just for testing; I've always advocated for testing the outcome rather than expectations.
If we want to check how many internal circular buffers has been made, we can always check the overall outcome, we know that if two circular buffers are made, at least we should have 2048 + 1, this at the FixedTaskQueue level.

At the FixedQueue we can go deep but always using the interfaces as a bridge and not going beyond

Copy link
Contributor Author

@JaoodxD JaoodxD May 24, 2024

Choose a reason for hiding this comment

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

I completely agree that it's not the right way. I just worry about further consequences due to the lack of clarity.
Is there anything else blocking the PR from being landed?

@metcoder95 metcoder95 merged commit 5a2f0e0 into piscinajs:current May 26, 2024
13 checks passed
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.

None yet

2 participants