ScheduledThreadPoolExecutor和HashedWheelTimer比较
Stack Overflow原文:java - HashedWheelTimer vs ScheduledThreadPoolExecutor for higher performance - Stack Overflow
10
6
I'm figuring what a timer implementation to use if you need to schedule tons of (non blocking) tasks as fast as possible inside jvm on one machine.
I've studied
ScheduledThreadPoolExecutor
andHashedWheelTimer
sources (+wheel timer general docs) and here are basic differences (N - number of all outstanding scheduled tasks so far, C - wheel size):ScheduledThreadPoolExecutor
- O(log N) for adding new task
- O(1) per each timer tick (but tick per each task, so N overall)
- O(log N) cancelling the task
- lock per each tick/task
HashedWheelTimer
- O(1) adding new task
- O(m) per each timer tick (m ~ N/C where C > 512 approx), so ~C ticks overall
- O(m) for cancelling a task
- lock per bucket of tasks (on each tick)
Thus I tend using HW Timer for such use-case, because you must schedule tasks quickly with minimum overhead, i.e. O(1) for new task. Also you will minimize a bookkeeping activity, because you'll get less number of ticks (N < C) and less lock contention. Canceling is not very important feature in this case
Did anybody try these timers for similar activities and what results see in practice? Thanks!
水友回答
The fundamental difference between them is that HWT is optimized for scheduling with tolerance for timing imprecision. If you can live with its imprecision, then it is almost certainly the better choice.
- Thanks, yes, a throughput (say per second) is more important for me than individual task accurate scheduling. On the other hand I doubt STPE would be very accurate on the heavy load and with huge work-queue. And you may get HWT more accurate after tuned tick-size in this case. Jun 24, 2013 at 13:35
水友回答二
2
HWT. Unless you require to-the-ns-precision, use the HWT. For most client-server applications, a HWT is sufficient. In many internet-scale applications, especially for in-memory caches that were the timeout was constantly changing, it was the only option. We're talking about billions of jobs here.
Actually, if you require that level of precision, you need a system with guaranteed interrupt times and not GC pauses; i.e. not Java, not Intel... :)
中文译文版本:
如果您需要在一台机器上尽可能快地在jvm中安排大量(非阻塞)任务,我计算出要使用哪个计时器实现。 我已经学习了
ScheduledThreadPoolExecutor
和HashedWheelTimer
来源(+ wheel定时器常规文档),以下是基本差异(N - 迄今为止所有未完成预定任务的数量,C轮大小): 的ScheduledThreadPoolExecutorHashedWheelTimer
- O(log N)添加新任务
- 每个计时器滴答(O)(1),但每个任务滴答,因此总体上N)
- O(log N)取消任务
- 每个滴答/任务锁定
- (1)添加新任务 每个计时器滴答(O~m)(m~N / C,其中C> 512),所以~C滴答总体
- O(m)取消任务
- 锁定每桶任务(每个滴答)
因此,我倾向于使用硬件定时器来处理这种用例,因为您必须以最小的开销快速地安排任务,即O(1)用于新任务。 此外,您还可以最大限度地减少簿记活动,因为您可以获得更少的刻度(N
所以我们看到,我们大部分场景都不需要有纳秒级别的精确度,所以使用HashedWheelTimer可以让我们的处理速度更快,将超时时间不同但相差不大的多个任务在同一个tick内得到处理。