许多年前,在处理严格的图形I / O问题时,Tom Duff展开了一个循环并创建了他的Duff's Device,如下所示:
dsend(to, from, count)
char *to, *from;
int count;
{
int n = (count + 7) / 8;
switch (count % 8) {
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while (--n > 0);
}
}
(注意这使用旧式函数参数 - 这不是错误。)
这种编码直接来自于汇编程序和C编码的思考,并且依赖于C的case语句落实。隔行扫描控制结构中的这种创造力能否适用于任何其他语言?
答案 0 :(得分:5)
你可以用支持计算GOTO语句的任何语言(Fortran,一些BASIC等)来实现它。
答案 1 :(得分:4)
它适用于C ++。
请注意,生成的代码取决于您的编译器。特别是,当我使用针对ARM体系结构的GCC编译Duff的设备时,生成的ARM汇编程序在任何优化级别都是次优的(我认为GCC将其转换为跳转表)。
我最后只是把汇编程序编码。
答案 2 :(得分:3)
Duff的设备本质上是一个计算goto
,可以用许多其他语言完成 - 汇编(当然)和FORTRAN是一对直接支持它们的。
答案 3 :(得分:3)
我在JavaScript中非常成功地使用它来加速大型数组处理。我希望我能在C#中使用它。
答案 4 :(得分:0)
即使不能以这种方式使用,您仍可能有两个循环:
count
当使用较小的count
时,这会稍慢一些,但它更具可读性,在语言上更具可移植性,并且与大 int delay = 3000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.exit(0);
}
};
new Timer(delay, taskPerformer).start();
产生非常相似的好处。