9

我们知道Duff 的设备利用交错结构的贯穿开关和循环,例如:

send(to, from, count)
register short *to, *from;
register count;
{
    register 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);
    }
}

现在,在 Swif 2.1 中,switch-case 控制流并没有像我们在 Swift 文档中所读到的那样隐式地失败:

没有隐式失败

与 C 和 Objective-C 中的 switch 语句相比,Swift 中的 switch 语句默认情况下不会落入每个案例的底部并进入下一个案例。相反,整个 switch 语句在第一个匹配的 switch case 完成后立即完成执行,而不需要显式的 break 语句。这使得 switch 语句比在 C 中更安全、更容易使用,并且避免了错误地执行多个 switch case。

现在,鉴于在 Swift 中有一个 fallthrough 子句具有明确的 fallthrough 副作用:

穿越

Swift 中的 Switch 语句不会从每个案例的底部落入下一个案例。相反,一旦第一个匹配的 case 完成,整个 switch 语句就完成了它的执行。相比之下,C 要求您在每个 switch 案例的末尾插入显式 break 语句以防止失败。避免默认失败意味着 Swift switch 语句比 C 中的对应语句更简洁和可预测,因此它们避免了错误地执行多个 switch 案例。

这很像:

let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += " a prime number, and also"
    fallthrough
default:
    description += " an integer."
}
print(description)
// prints "The number 5 is a prime number, and also an integer."

考虑到 Wikipedia 提醒我们,这些设备来自问题

A straightforward code to copy items from an array to a memory-mapped output register might look like this:
do {                          /* count > 0 assumed */
    *to = *from++;            /* "to" pointer is NOT incremented, see explanation below */
} while(--count > 0);

哪个是Swift 中 Duff 设备的确切实现?

这只是一个语言和编码问题,并不打算应用于真正的 Swift 应用程序。

4

2 回答 2

3

Duffs 设备不仅仅是优化。如果您查看https://research.swtch.com/duff,它会讨论使用此机制实现协同例程(参见第 8 段,了解 Duff 先生的评论)。

如果你尝试编写一个没有这个能力的可移植协程包。您最终会组装或重新编写 jmpbuf 条目 [两者都不是可移植的]。

像 go 和 swift 这样的现代语言比 C 有更多限制性的内存模型,所以这种机制(我想)会导致各种跟踪问题。即使是 clang,gcc 中类似 lambda 的块结构最终也会与线程本地存储交织在一起,除非您坚持使用琐碎的应用程序,否则可能会造成各种破坏。

于 2019-07-09T23:14:52.997 回答
2

你尽可能用最高级别的代码表达你的意图,并相信 Swift 编译器会为你优化它,而不是试图自己优化它。Swift 是一门高级语言。您不会使用高级语言进行低级循环展开。

尤其是在 Swift 中,您不必担心复制数组(Duff 设备的原始应用程序),因为 Swift 会假装在您分配数组时使用“写入时复制”来复制数组。这意味着只要您只是从它们中读取,它将对两个变量使用相同的数组,但是一旦您修改其中一个,它将在后台创建一个副本。

例如,从https://developer.apple.com/documentation/swift/array 修改数组的副本

Each array has an independent value that includes the values of all
of its elements. For simple types such as integers and other structures,
this means that when you change a value in one array, the value of that
element does not change in any copies of the array. For example:

var numbers = [1, 2, 3, 4, 5]
var numbersCopy = numbers
numbers[0] = 100
print(numbers)
// Prints "[100, 2, 3, 4, 5]"
print(numbersCopy)
// Prints "[1, 2, 3, 4, 5]"
于 2017-12-16T18:47:13.690 回答