Backs Pool with ConcurrentLinkedQueue instead of ArrayBlockingQueue.#405
Backs Pool with ConcurrentLinkedQueue instead of ArrayBlockingQueue.#405
Conversation
Codecov Report
@@ Coverage Diff @@
## master #405 +/- ##
============================================
+ Coverage 66.42% 66.43% +0.01%
+ Complexity 5386 5385 -1
============================================
Files 155 155
Lines 22701 22705 +4
Branches 4093 4093
============================================
+ Hits 15080 15085 +5
+ Misses 6261 6259 -2
- Partials 1360 1361 +1
Continue to review full report at Codecov.
|
|
Note: the performance regression test failed for an unrelated reason ( |
zslayton
left a comment
There was a problem hiding this comment.
After the change, polling and offering the queue basically disappears from the profile. Even if this doesn't have a large performance impact in most cases, I'd be happy to merge it just to clean up performance profiles. It also has the benefit of added consistency with our other pool implementation.
Agreed; this is a good change but I would love to know where the JVM is spending its newfound free time.
Some minor cleanup thoughts below.
| @@ -1,6 +1,8 @@ | |||
| package com.amazon.ion.impl.bin.utf8; | |||
There was a problem hiding this comment.
This class started out as a Utf8EncoderPool and was generalized when we realized how many different resources we could be pooling. We should consider promoting Pool<T> to a higher-level package.
There was a problem hiding this comment.
True; I'll leave that for its own PR. Issue to track: #406
|
|
||
| // A queue of previously initialized objects that can be loaned out. | ||
| private final ArrayBlockingQueue<T> bufferQueue; | ||
| private final Queue<T> bufferQueue; |
There was a problem hiding this comment.
I notice some pre-existing comments/variables mention things like buffer and block; these aren't accurate for the generalized Pool<T> type.
| private final Queue<T> bufferQueue; | |
| private final Queue<T> objectQueue; |
| // Under high contention, multiple threads could end up here before the first one | ||
| // decrements the size, causing blocks to be dropped wastefully. This is not harmful | ||
| // because blocks will be re-allocated when necessary; the pool is kept as close as |
There was a problem hiding this comment.
| // Under high contention, multiple threads could end up here before the first one | |
| // decrements the size, causing blocks to be dropped wastefully. This is not harmful | |
| // because blocks will be re-allocated when necessary; the pool is kept as close as | |
| // Under high contention, multiple threads could end up here before the first one | |
| // decrements the size, causing objects to be dropped wastefully. This is not harmful | |
| // because objects will be re-allocated when necessary; the pool is kept as close as |
91f97f0 to
1d29044
Compare
Issue #, if available:
Resolves #403
Description of changes:
#403 was created in response to a user report that ArrayBlockingQueue was performing poorly under high contention. This PR proposes to use ConcurrentLinkedQueue instead, as we do in the binary writer's PooledBlockAllocator. Now, the implementation of both pools is practically identical.
I tested the performance by reading a small binary Ion payload using 256 different threads simultaneously. My results did not capture much impact to raw performance, as is shown below.
Before:
After:
However, I did notice a significant difference on the CPU profiles before and after the change. The "before" profile closely resembles the profile the requester showed me.
Before:
After:
After the change, polling and offering the queue basically disappears from the profile. Even if this doesn't have a large performance impact in most cases, I'd be happy to merge it just to clean up performance profiles. It also has the benefit of added consistency with our other pool implementation.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.