大家好,又见面了,我是你们的朋友全栈君。
即使是循环中最快的代码,累计迭代上千次也会慢下来。此外,循环体运行时也会带来小性能开销,不仅仅是增加了总体运行时间。减少迭代次数能获得更加显著的性能提升,最广为人知的一种限制循环迭代次数的模式被称为“达夫设备(Duff’s Device)”。
Duff’s Device是一种循环体展开技术,它使得一次迭代中实际执行了多次迭代的操作。一个典型的实现如下:
<script type="text/javascript">
var iterations = Math.floor(items.length/8),
startAt = items.length % 8,
i = 0;
do {
switch(startAt) {
case 0: process(items[i++]);
case 7: process(items[i++]);
case 6: process(items[i++]);
case 5: process(items[i++]);
case 4: process(items[i++]);
case 3: process(items[i++]);
case 2: process(items[i++]);
case 1: process(items[i++]);
}
startAt = 0;
}while(--iterations);
</script>
达夫设备背后的基本理念是:每次循环中最多可8次调用process()函数。循环迭代次数为元素总数除以8.因为总数不一定是8的整数倍,所以startAt变量存放余数,指出第一次循环中应当执行多少次process()。比方说现在有12个元素,那么第一次循环将调用process()4次,第二次循环调用process()8次,用2次循环代替了12次循环。
次算法一个稍快的版本取消了switch表达式,将余数处理与主循环分开:
<script type="text/javascript">
var i = items.length % 8;
while(i){
process(items[i--]);
}
i = Math.floor(items.length / 8);
while (i) {
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
}
</script>
虽然此代码中使用两个循环替代了先一个循环,但它去掉了循环体重的switch表达式,速度更快。
是否值得使用达夫设备,无论是原始的版本还是修改后的版本,很大程度上依赖于迭代的次数。如果循环迭代次数少于1000次,你可能只看到它与普通循环相比只有微不足道的性能提升。如果迭代次数超过1000次,达夫设备的效率明显提升。例如500000次迭代中,运行时间比普通循环减少到70%。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/192984.html原文链接:https://javaforall.cn