使用方案我需要使用以下功能。 (所有args都是自然数[0,inf))
(define safe-div
(lambda (num denom safe)
(if (zero? denom)
safe
(div num denom))))
但是,此功能经常被调用,并且表现不佳(速度快)。 是否有更有效的方法来实现所需的行为(num和denom的整数除法,如果denom为零则返回安全值)?
注意,我使用的是Chez Scheme,但是这个用于只导入rnrs的库,而不是完整的Chez。
答案 0 :(得分:6)
为获得最佳性能,您需要尽可能接近硅片。除非他们通过方案系统及时编译成超高效的机器代码,否则添加这样的安全检查是不可能做到的。
我看到两个选项。一种是在C(或程序集)中创建本机(即foreign)实现并调用它。这可能与将其打包为lambda无法兼容,但同样,lambdas的动态特性导致符号效率,但不一定导致运行时效率。 (函数指针除外,其中有一个原因lambda表达式在C中不存在,尽管年龄要长许多。)如果你走这条路,最好退后一步,看看哪个更大的处理安全-div应该是原生的一部分。如果围绕它的所有东西仍然很慢,那么加速循环中心的分割是没有意义的。
假设预期除零很少,另一种方法是使用div
并希望它的实现速度很快。是的,这可以导致除以零,但是当谈到速度时,有时候请求宽恕比要求许可更好。换句话说,跳过分割前的检查,然后就可以了。如果失败,方案运行时应该捕获除零错误,并且可以为它安装exception handler。这导致异常情况下的代码更慢,而正常情况下代码更快。希望这种权衡取得成功。
最后,根据您所分割的内容,乘以倒数可能比执行实际除法更快。这需要快速相互计算或修改早期计算以直接产生倒数。由于您正在处理整数,因此倒数将存储在定点中,基本上为2 ^ 32 * 1 / denom。将此乘以num并向右移32位以获得商。这取决于胜利,因为现在更多的处理器具有单周期乘法指令,但是除法在芯片上的循环中执行,这要慢得多。这可能对您的需求来说太过分了,但在某些时候可能会有用。