Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有swiftc编译器优化来删除不必要的大变量?_Swift_Compiler Optimization - Fatal编程技术网

是否有swiftc编译器优化来删除不必要的大变量?

是否有swiftc编译器优化来删除不必要的大变量?,swift,compiler-optimization,Swift,Compiler Optimization,当我使用高阶函数编写代码时,我发现一次编写一个转换表达式要干净得多,如下所示: let children = objects.map { $0.children } let validChildren = children.filter { $0.isValid } let sortedChildren = validChildren.sorted { $0.count < $1.count } let children=objects.map{$0.children} 设validCh

当我使用高阶函数编写代码时,我发现一次编写一个转换表达式要干净得多,如下所示:

let children = objects.map { $0.children }
let validChildren = children.filter { $0.isValid }
let sortedChildren = validChildren.sorted { $0.count < $1.count }
let children=objects.map{$0.children}
设validChildren=children.filter{$0.isValid}
let sortedChildren=validChildren.sorted{$0.count<$1.count}
但是,我知道这些函数中的每一个都会返回一个新的数组对象,我将其存储到一个变量中,因此理论上我每次都会创建并保留一个新数组,这会浪费大量内存。最好将调用写为一行,以便在使用后销毁不必要的数组

let sortedChildren = objects.map { $0.children } .filter { $0.isValid } .sorted { $0.count < $1.count }
let sortedChildren=objects.map{$0.children}.filter{$0.isValid}.sorted{$0.count<$1.count}

但是,由于一行代码中发生了太多的事情,因此这在以后阅读时要烦人得多。所以我的问题是:斯威夫特的编译器是否有一个优化来原谅我的挑剔,并在编译时删除未使用的变量?

这是@MartinR在问题评论中提到的,但值得一个正式的答案和来源

Swift中的所有标准库容器都是使用COW的值类型 (写拷贝)[4]执行拷贝而不是显式拷贝。在里面 在许多情况下,这允许编译器通过 保留容器而不是执行深度复制。这是 仅通过复制基础容器(如果引用计数为 容器的值大于1,并且容器发生了变异。对于 在下面的实例中,将d分配给时不会发生复制 c、 但当d通过附加2进行结构突变时,d将 复制,然后将2追加到d:


由于高阶函数不会修改它们所调用的对象,因此可以很有信心地说,结果是针对大小进行优化的。

这是@MartinR在问题评论中提到的,但值得一个官方答案和来源

Swift中的所有标准库容器都是使用COW的值类型 (写拷贝)[4]执行拷贝而不是显式拷贝。在里面 在许多情况下,这允许编译器通过 保留容器而不是执行深度复制。这是 仅通过复制基础容器(如果引用计数为 容器的值大于1,并且容器发生了变异。对于 在下面的实例中,将d分配给时不会发生复制 c、 但当d通过附加2进行结构突变时,d将 复制,然后将2追加到d:


由于高阶函数不会修改它们所调用的对象,因此可以很有把握地说,结果针对大小进行了优化。

两个版本之间没有什么不同

即使没有将结果分配给变量,也会创建列表的一个新实例以存储函数调用的结果。因此,内存使用是相同的

objects.map { $0.children }.filter { $0.isValid }.sorted { $0.count < $1.count }
objects.map{$0.children}.filter{$0.isValid}.sorted{$0.count<$1.count}

因此,在每次函数调用之后,我们仍然需要内存来存储该函数的结果,无论您是否将其分配给变量。将赋值给另一个变量不会复制对象。

两个版本之间没有区别

即使没有将结果分配给变量,也会创建列表的一个新实例以存储函数调用的结果。因此,内存使用是相同的

objects.map { $0.children }.filter { $0.isValid }.sorted { $0.count < $1.count }
objects.map{$0.children}.filter{$0.isValid}.sorted{$0.count<$1.count}

因此,在每次函数调用之后,我们仍然需要内存来存储该函数的结果,无论您是否将其分配给变量。而
赋值给另一个变量不会复制对象。

“一行代码中有太多内容”–请注意,您可以在
.filter
.sorted
之前中断行。这听起来像是过早优化。不,编译器不会在意您将其拆分为不同的变量。但是如果你担心内存问题,你可以按照@MartinR说的做,使用换行符,或者你至少可以将变量声明为private/fileprivate或lazy。此外,数组是“写时拷贝”,这使得未修改的拷贝“便宜”——你分析过你的两个版本之间是否真的有差异吗?@MartinR当然,但这仍然可以作为一条指令,并且比第一个选项噪音大得多。但我的问题主要是关于编译器优化。考虑到swiftc的年龄相对较轻,我不确定它的可用功能。“一行代码中发生了太多事情”-请注意,您可以在
.filter
之前以及
.sorted
之前中断该行。这听起来像是过早的优化。不,编译器不会关心您将其拆分为不同的变量。但是如果你担心内存问题,你可以按照@MartinR说的做,使用换行符,或者你至少可以将变量声明为private/fileprivate或lazy。此外,数组是“写时拷贝”,这使得未修改的拷贝“便宜”——你分析过你的两个版本之间是否真的有差异吗?@MartinR当然,但这仍然可以作为一条指令,并且比第一个选项噪音大得多。但我的问题主要是关于编译器优化。我不确定swiftc的可用功能,因为它相对年轻。