达夫设备(Duff’s Device)

达夫设备(Duff’s Device)的技术。
该技术是以其发明者 Tom Duff 命名的,他最早建议在 C 语言中使用该技术。在 JavaScript 实现达夫设备的人是 Jeff Greenberg。
达夫设备的基本思路是以 8 的倍数作为迭代次数从而将循环展开为一系列语句。

// 来源:Jeff Greenberg 在 JavaScript 中实现的达夫设备
// 假设 values.length > 0
let iterations = Math.ceil(values.length / 8);
let startAt = values.length % 8;
let i = 0;
do {
 switch(startAt) {
   case 0: process(values[i++]); // 注意:没有 break,因此目标 case 后面的语句都会执行
   case 7: process(values[i++]);
   case 6: process(values[i++]);
   case 5: process(values[i++]);
   case 4: process(values[i++]);
   case 3: process(values[i++]);
   case 2: process(values[i++]);
   case 1: process(values[i++]);
 }
 startAt = 0;
} while (--iterations > 0);

Andrew B. King 在 Speed Up Your Site 一书中提出了更快的达夫设备实现,他将 do-while 循环分成了两个单独的循环,如下所示:

// 来源:Speed Up Your Site(New Riders,2003)
let iterations = Math.floor(values.length / 8);
let leftover = values.length % 8;
let i = 0;
if (leftover > 0) {
 do {
   process(values[i++]);
 } while (--leftover > 0);
}
do {
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
} while (--iterations > 0);

在这个实现中,变量 leftover 保存着只按照除以 8 来循环不会处理,因而会在第一个循环中处理
的次数。处理完这些额外的值之后进入主循环,每次循环调用 8 次 process()。这个实现比原始的实
现快约 40%。
展开循环对于大型数据集可以节省很多时间,但对于小型数据集来说,则可能不值得。因为实现同
样的任务需要多写很多代码,所以如果处理的数据量不大,那么显然没有必要

posted @ 2022-10-25 18:02  Better-HTQ  阅读(289)  评论(0编辑  收藏  举报