13.4.7 优化常见的情况

区分最常见的情况和最坏可能的情况并且分别处理它们,这通常是一个好主意。针对这两者的代码常常是相当不同的。重要的是要使常见的情况速度快。对于最坏的情况,如果它很少发生,使其正确就足够了。

第一个例子,考虑进入一个临界区。在大多数时间中,进入将是成功的,特别是如果进程在临界区内部不花费很多时间的话。Windows Vista提供的一个Win32 API调用EnterCriticalSection就利用了这一期望,它自动地在用户态测试一个标志(使用TSL或等价物)。如果测试成功,进程只是进入临界区并且不需要内核调用。如果测试失败,库过程将调用一个信号量上的down操作以阻塞进程。因此,在通常情况下是不需要内核调用的。

第二个例子,考虑设置一个警报(在UNIX中使用信号)。如果当前没有警报待完成,那么构造一个警报并且将其放在定时器队列上是很简单的。然而,如果已经有一个警报待完成,那么就必须找到它并且从定时器队列中删除。由于alarm调用并未指明是否已经设置了一个警报,所以系统必须假设最坏的情况,即有一个警报。然而,由于大多数时间不存在警报待完成,并且由于删除一个现有的警报代价高昂,所以区分这两种情况是一个好主意。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

做这件事情的一种方法是在进程表中保留一个位,表明是否有一个警报待完成。如果这一位为0,就好办了(只是添加一个新的定时器队列项而无须检查)。如果该位为1,则必须检查定时器队列。