AutoMQ/automq

[Enhancement] avoid creating 3000 useless block objects per second by default

CLFutureX opened this issue · 1 comments

Background:
In com.automq.stream.s3.wal.impl.block.SlidingWindowService#pollBlocks, at the current default frequency of 3000 IOPS, it is equivalent to creating 3000 useless block objects every second (within the block there are multiple global object creations, and there are also system method calls like this.startTime = System.nanoTime()).

Optimization :

A minor change here can yield significant benefits:
When polling blocks, if pendingBlocks is not empty, it can be determined that currentBlock has certainly not exceeded the current interval time.
In this case, we do not need to consider currentBlock, thus avoiding the creation of useless blocks.

Only when pendingBlocks is empty, there is a possibility that the creation time of currentBlock has exceeded the interval time, and then currentBlock should be considered.

Hello, the issue you described does indeed exist. In the current implementation, up to 3000 useless empty Block can be generated per second.
At that time, we did consider other implementations, such as using some auxiliary markers to replace an empty Block object. However, for the sake of code readability, we ultimately did not do so.

According to our most recent stress test results (June 7, 2024, version 1.1.0), the overhead of this operation is actually very small, as shown in the figures below:

image
CPU Flame Graph

image
Memory Allocation Flame Graph

As you can see, the occupancy of BlockImpl.<init> is very small, to the extent that it was not sampled in the CPU flame graph. Similarly, the number of objects it allocates only accounts for 0.03% of the total number, which is also negligible.

Furthermore, in the solution you proposed, you mentioned:

When polling blocks, if pendingBlocks is not empty, it can be determined that currentBlock has certainly not exceeded the current interval time.

This is not incorrect, but I think that writing currentBlock as early as possible brings more benefits (compared to the overhead it brings, which is an empty object Block).

In summary, I believe this is not an area worth optimizing at the moment, and maintaining the status quo is a better choice.