gpt4 book ai didi

java - 了解异步记录器中的环形缓冲区

转载 作者:行者123 更新时间:2023-12-01 14:21:25 24 4
gpt4 key购买 nike

在 log4j2 的异步记录器中 mannual link

log4j2.asyncLoggerConfigRingBufferSize 的默认值为 256 * 1024

这里2561024代表什么?

最佳答案

ringbuffer 中的槽数需要是 2 的幂。这允许您不断递增计数器并使用位掩码而不是模数从计数器获取数组索引。

例如,假设我们有一个大小为 4 的环形缓冲区。索引 03 是数组中的有效索引。我们想避免检查 index++;如果(索引 > 3){ 索引 = 0; }。在紧密循环中,此 if 检查会减慢速度。我们能避免吗?

是的,我们可以。我们可以只增加而不检查,当我们从数组中获取一个值时,我们忽略所有 4 的倍数(数组的大小)。人们通常为此使用取模操作:value = array[index % 4];

3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
...

这很好用,但我们可以做得更好。模运算适用于任何数组大小,但我们选择数组大小为 2 的幂是有原因的:位掩码!位掩码可以实现相同的目的,但速度要快得多(大约快 25 倍)。

这是如何运作的?如果数组是二的幂,我们通过减一得到它的位掩码。然后我们在从数组中获取值时使用此掩码:value = array[index & mask];

对于4,位掩码是4-1=3。 3用二进制表示是11。让我们看一下与之前相同的示例:

0011 & 0011 = 0011 (3 & 3 = 3)
1000 & 0011 = 0000 (4 & 3 = 0)
1001 & 0011 = 0001 (5 & 3 = 1)
...

所以这与取模相同,但速度更快。同样,关键点是数组需要是 2 的倍数。

回到问题:ringbuffer中实际的槽数是262144。文档声明 256 * 1024 以阐明这是 2 的幂。

关于java - 了解异步记录器中的环形缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50887089/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com