Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@guizmaii
Copy link
Member

@guizmaii guizmaii commented Apr 9, 2025

No description provided.

@guizmaii guizmaii marked this pull request as ready for review April 9, 2025 09:42
Comment on lines -99 to -102
take.flatMap { b =>
takeRemainder(remaining - 1, max - bs.length - 1, acc ++ bs :+ b)

}
Copy link
Member Author

@guizmaii guizmaii Apr 9, 2025

Choose a reason for hiding this comment

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

I'm not sure to understand what this take in this remaining > 1 case was bringing
IMO, it'll be faster to just loop as it'll avoid to execute 1 take and then a takeUpTo. Instead it's just execute takeUpTo

Copy link
Contributor

Choose a reason for hiding this comment

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

AFAICT it's quite important. takeUpTo will return a Chunk.empty immediately if the queue is empty, but take will asynchronously wait until something is placed in the queue and the calling thread will be notified via the completion of a Promise. With this implementation we're not asynchronously suspending awaiting for an item to be placed in the queue which wastes CPU cycles (potentially indefinitely)

Copy link
Member Author

@guizmaii guizmaii Apr 10, 2025

Choose a reason for hiding this comment

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

My bad :/

Fixed

Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we add a test for this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add a test for this?

I'll see if I can come up with one in a followup PR

@guizmaii guizmaii requested a review from kyri-petrou April 9, 2025 09:44
@guizmaii guizmaii force-pushed the opt_dequeue_takeBetween branch from d4af989 to fd97e43 Compare April 9, 2025 10:15
@guizmaii guizmaii requested review from ghostdogpr and hearnadam April 9, 2025 10:23
Copy link
Contributor

@kyri-petrou kyri-petrou left a comment

Choose a reason for hiding this comment

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

I think we need to put the extra take back as this implementation will not asynchronously suspend when the queue is empty. Do you think we can keep some of the other optimizations?

PS: I think the outer ZIO.suspendSucceed can be removed as well

Comment on lines -99 to -102
take.flatMap { b =>
takeRemainder(remaining - 1, max - bs.length - 1, acc ++ bs :+ b)

}
Copy link
Contributor

Choose a reason for hiding this comment

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

AFAICT it's quite important. takeUpTo will return a Chunk.empty immediately if the queue is empty, but take will asynchronously wait until something is placed in the queue and the calling thread will be notified via the completion of a Promise. With this implementation we're not asynchronously suspending awaiting for an item to be placed in the queue which wastes CPU cycles (potentially indefinitely)

@guizmaii guizmaii changed the title Optimize Dequeue#takeBetween Clean Dequeue#takeBetween code Apr 10, 2025
@guizmaii guizmaii requested a review from kyri-petrou April 10, 2025 01:09
@guizmaii guizmaii force-pushed the opt_dequeue_takeBetween branch from d6a17a2 to 11d1369 Compare April 10, 2025 05:19

if (remaining <= 0) Exit.succeed(acc ++ bs)
else if (remaining == 1) take.map(b => acc ++ bs :+ b)
else take.flatMap(b => takeRemainder(remaining - 1, max - bs.length - 1, acc ++ bs :+ b))
Copy link
Contributor

Choose a reason for hiding this comment

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

@guizmaii I'm thinking that while this is okay for small min / max numbers, it's probably quite unoptimized for large numbers due to the concatenation of Chunks. I wonder if we could use a ChunkBuilder instead when min or max are relatively large.

However perhaps lets look at this at another PR

Copy link
Member Author

Choose a reason for hiding this comment

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

That's a good question. I don't really understand well how Chunk/ChunkBuilder are working nor how to get best performances from then, especially about concatenating two Chunk/ChunkBuilder

I know that Chunks concatenation doesn't relocate immediately a new Chunk containing both. It's using final case class Concat[A](override protected val left: Chunk[A], override protected val right: Chunk[A]) to concat lazily

Why do you think using ChunkBuilder would help?

kyri-petrou
kyri-petrou approved these changes Apr 10, 2025
@guizmaii guizmaii merged commit bba4aab into series/2.x Apr 10, 2025
18 checks passed
@guizmaii guizmaii deleted the opt_dequeue_takeBetween branch April 10, 2025 06:59
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.

3 participants