-
Couldn't load subscription status.
- Fork 1.4k
Clean Dequeue#takeBetween code
#9768
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
Conversation
| take.flatMap { b => | ||
| takeRemainder(remaining - 1, max - bs.length - 1, acc ++ bs :+ b) | ||
|
|
||
| } |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad :/
Fixed
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
d4af989 to
fd97e43
Compare
There was a problem hiding this 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
| take.flatMap { b => | ||
| takeRemainder(remaining - 1, max - bs.length - 1, acc ++ bs :+ b) | ||
|
|
||
| } |
There was a problem hiding this comment.
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)
d6a17a2 to
11d1369
Compare
|
|
||
| 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)) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
No description provided.