-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
(feat) Impl SegmentList to replace ArrayDequeue in LogManagerImpl, #335 #377
Conversation
*/ | ||
public class SegmentList<T> { | ||
private static final int SEGMENT_SHIFT = 8; | ||
public static final int SEGMENT_SIZE = 2 << (SEGMENT_SHIFT - 1); |
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.
every segment contains at most 128 elements, but SEGMENT_SIZE 2 << 7 equals 256.
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.
Fixed. 128 is a balance between time and space.
|
||
@SuppressWarnings("unchecked") | ||
public void addAll(final Collection<T> coll) { | ||
Object[] src = coll.toArray(); |
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.
入参为 Collection 类型更通用,原有 ArrayDeque 的设计也没有避免一次 toArray 的多余 memcopy
但我还是建议这里针对 ArrayList 做一个 fast path 优化,在入参 coll 为 ArrayList 类型且 UnsafeUtil.hasUnsafe() == true
的情况下通过 UnsafeReferenceFieldUpdater
直接拿到 ArrayList 中的 object[]
,用于后面的 copy,这样节省了一次 memcopy;
AppendEntries()
是 jraft 中的热点执行路径,会调用 addAll ()
来 append log,所以我认为即使代码丑一点,但是优化是值得的,理论上会减少大量的 toArray 带来的临时 'object[]' 的创建和 memcopy
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.
嗯,搞了下,测试下来,稳定提升在 15% 以上 👍 ,不过需要将 UnsafeReferenceFieldUpdater 从 rheakv 拷贝一份到 jraft-core 。不做 move,因为不确定外面有没有人依赖了。
这个图是不是可以加到 |
Updated:
|
Motivation:
See #335
Modification:
SegmentList
that is a list of segment, every segment is an array contains 128 elements, and only supports removing elements from start or end:The
removeFromFirstWhen
andremoveFromLastWhen
methods accept a predicate and delete the elements from start or end until the predicate returns false. Theremove
operation only set the elements to be null and remeber the deleted poistion,do not have any array elements movement at all. If a segment is empty afterremove
, it will be removed from segment list too.Also, I use the
Recyclable
to reuse theSegment
instances.The
SegmentList
performance in benchmark is alaways better thanArrayDequeue
inSegmentListTest#simpleBenchmark
, at most 10% improvement(The benchmark has some random factor).ArrayDeque
inLogManagerImpl
withSegmentList
RepeatedTimer#destroy
andRepeatedTimer#run
Result:
Fixes #335