2017-03-17 57 views
0

我知道,通过在Swift中最终生成属性和方法,我可以提高编译时间和应用程序的性能。最近我阅读苹果博客文章:https://developer.apple.com/swift/blog/?id=27,其中指出,使财产或方法(文件)私人(博客发布日期为2015年,当“私人”意味着“fileprivate”)使编译器推断属性或方法的“最终”在源文件中搜索任何覆盖。但是,“真正的”(Swift 3)私人?编译器不应该搜索任何地方的潜在覆盖,所以我的问题是:

这两个声明之间是否有任何性能和/或编译时间差异?Swift - private var/func vs private final var/func

private final var foo: Int 

private var bar: Int 
+0

在第一个中,您无法更改曾经赋值的值,并且只能在该类中访问该值。第二个值可以更改值,并且只能在同一个类中访问。 –

+0

对不起,我的问题可能还不够具体。我这两个声明做了什么(而且你的声明是不正确的:你可以给最终变量赋值 - 它不是Java)。我想知道他们之间是否有任何性能差异。 – MikChmie

+0

不,没有性能问题。 –

回答

1

我做了2级简单的类:

class UseFinal 
{ 
    private final var foo = 1 
} 

class NoUseFinal 
{ 
    private var foo = 1 
} 

,并运行下面的代码:

var start = Date() 
for _ in 1...100000 
{ 
    let temp = NoUseFinal() 
} 
print("noUseFinal took \(Date().timeIntervalSince(start))") 

start = Date() 
for _ in 1...100000 
{ 
    let temp = UseFinal() 
} 
print("useFinal took \(Date().timeIntervalSince(start))") 

结果一致显示,加入 “最终” 明确跑得更快。一个样本输出:

noUseFinal took 0.0214230418205261 
useFinal took 0.0155709981918335 

编辑

出于好奇,因为以前的错字,我试着开关的顺序for循环,使得UseFinal类先打。这导致这个课程花费更长的时间:即时间与其他时间几乎相同,只是现在UseFinal时间更长。这使我现在相信......没有区别。我认为他们在一天结束时会完全相同。

+0

不错的比较。你可以(或其他人)提供关于编译时间的任何反馈吗? – MikChmie

0

标记为private的方法或属性暗含为final。 从@conarch提供的测试是一个副作用 - 调度类。

我做出同样的试验,休耕:

class UseFinal { 
     private final var foo = 1 
    } 

    class NoUseFinal { 
     private var foo = 1 
    } 

    var start = Date() 
    print(NoUseFinal()) 
    print(UseFinal()) 
    print("construct takes \(Date().timeIntervalSince(start))") 

    start = Date() 
    for _ in 1...1_000_000 { 
     let temp = NoUseFinal() 
    } 
    print("noUseFinal took \(Date().timeIntervalSince(start))") 

    start = Date() 
    for _ in 1...1_000_000 { 
     let temp = UseFinal() 
    } 
    print("useFinal took \(Date().timeIntervalSince(start))") 

    print("----") 
    start = Date() 
    for _ in 1...1_000_000 { 
     let temp = UseFinal() 
    } 
    print("useFinal took \(Date().timeIntervalSince(start))") 
    start = Date() 
    for _ in 1...1_000_000 { 
     let temp = NoUseFinal() 
    } 
    print("noUseFinal took \(Date().timeIntervalSince(start))") 

我得到的结果如下:

NoUseFinal 
UseFinal 
---- 
construct takes 0.000900983810424805 
noUseFinal took 0.182932019233704 
useFinal took 0.182898044586182 
---- 
useFinal took 0.183371007442474 
noUseFinal took 0.182500004768372 

因此,有调度员

0

privateprivate final方法或属性之间没有区别final用于减少运行时的动态调度。这样性能会更好。

程序必须在运行时确定引用哪个方法或属性,然后执行间接调用或间接访问。 这种技术称为动态调度。

private关键字用于可视性。如果编译器使用private发现没有重写声明,编译器将推断前面的final关键字,然后所有的调用都变为直接的。性能也得到改善。但应该不如final