1

使用方案我需要使用以下功能。(所有参数都是自然数 [0, inf) )

(define safe-div
  (lambda (num denom safe)
    (if (zero? denom)
        safe
        (div num denom))))

然而,这个函数经常被调用并且性能不够好(速度方面)。是否有更有效的方法来实现所需的行为(num 和 denom 的整数除法,如果 denom 为零则返回安全值)?

注意,我使用的是 Chez Scheme,但是它被用于仅导入 rnrs 而不是完整 Chez 的库中。

4

1 回答 1

7

为了获得最佳性能,您需要尽可能靠近硅片。添加这样的安全检查是行不通的,除非它们被方案系统及时编译成超高效的机器代码。

我看到两个选项。一种是在C(或程序集)中创建一个本地(即外部)实现并调用它。这可能与将其打包为 lambda 不兼容,但话又说回来,lambda 的动态特性导致符号效率,但不一定是运行时效率。(函数指针除外,C 中不存在 lambda 表达式是有原因的,尽管它已经老了很多年。)如果你走这条路,最好退后一步,看看哪个 safe-div 的更大处理是一部分应该是原生的。如果周围的一切仍然很慢,那么加速循环中心的划分就没有什么意义了。

假设被零除预计很少见,另一种方法是只使用div并希望它的实现速度很快。是的,这可能导致除以零,但在速度方面,有时请求宽恕比请求许可更好。换句话说,跳过除法前的检查,直接去做。如果失败,方案运行时应捕获除以零故障,您可以为其安装异常处理程序。这会导致异常情况下的代码变慢,而正常情况下的代码变快。希望这种权衡能够带来性能上的胜利。

最后,根据您要除以的内容,乘以倒数可能比执行实际除法更快。这需要快速的倒数计算或修改较早的计算以直接产生倒数。由于您正在处理整数,因此倒数将存储在定点中,本质上是 2^32 * 1/denom。将此乘以 num 并右移 32 位以获得商。这是成功的,因为如今更多的处理器具有单周期乘法指令,但除法在芯片上的循环中执行,这要慢得多。这可能对您的需求有点过分,但在某些时候可能会很有用。

于 2012-04-17T04:42:31.910 回答