在这些比较中,Swift如何比Objective-C快得多?


115

苹果在WWDC14上发布了其新的编程语言Swift。在演示中,他们对Objective-C和Python进行了一些性能比较。以下是其中一张幻灯片的图片,比较了执行某种复杂对象排序的这三种语言:

在此处输入图片说明

关于使用RC4加密算法的性能比较,还有一个更加令人难以置信的图表。

显然,这是一次市场营销讲座,他们没有详细介绍如何在每种情况下实施。我让我想知道:

  1. 一种新的编程语言怎么能这么快?
  2. Objective-C的结果是由错误的编译器引起的还是在客观上比Swift效率低?
  3. 您如何解释性能提高40%?我知道垃圾回收/自动引用控制可能会产生一些额外的开销,但是要多少呢?

13
@MathewFoscarini Obj-C转到汇编程序,但是它具有昂贵的对象消息分发机制。对于大多数GUI工作而言,这并不重要,但对于排序而言则非常重要。
Donal Fellows 2014年

17
与Python的比较才是真正的难题。
asthasr 2014年

9
@syrion营销,该语言似乎是从python的语法中借用的(很像golang)。他们试图说“嘿,Python开发人员,您可以在Mac上写一些不太陌生的东西,它的运行速度如此之快,甚至比您从未真正

4
@MichaelT我明白了,但还是很奇怪。任何对语言一无所知的人都会意识到,作为一种解释性语言,Python根本不会与Objective-C或其他编译语言(对于大多数任务)处于同一水平。用它作为基准很奇怪。
asthasr 2014年

7
它们可能意味着编写代码需要花费的时间...
Lukas Eder 2014年

Answers:


62

首先,(IMO)与Python进行比较几乎没有意义。只有与Objective-C进行比较才有意义。

  • 一种新的编程语言怎么能这么快?

Objective-C是一种慢语言。(只有C语言的部分很快,但是那是因为它是C)它从未如此之快。它的速度足以满足(Apple)的目的,并且比其旧版本要快。而且很慢,因为...

  • 是Objective-C是由错误的编译器导致的还是Objective-C的效率低于Swift?

Objective-C确保动态分配每种方法。完全没有静态调度。这使得不可能进一步优化Objective-C程序。好吧,也许JIT技术可能会有所帮助,但是AFAIK和Apple确实讨厌不可预测的性能特征和对象寿命。我认为他们没有采用任何准时制产品。除非您为Objective-C兼容性添加一些特殊的属性,否则Swift没有这种动态调度保证。

  • 您如何解释性能提高40%?我知道垃圾回收/自动引用控制可能会产生一些额外的开销,但是要多少呢?

GC或RC在这里无关紧要。Swift也主要使用RC。没有GC,除非GC技术在架构上有巨大飞跃,否则也不会。(IMO,这是永远的)我相信Swift拥有更多的静态优化空间。尤其是低级加密算法,因为它们通常依赖于庞大的数值计算,这对于静态调度语言来说是一个巨大的胜利。

其实我很惊讶,因为40%似乎太小。我期望更多。无论如何,这是最初的版本,我认为优化不是主要问题。Swift甚至还不够完善!他们会做的更好。

更新资料

有些人一直困扰我,认为GC技术是卓越的。尽管下面的内容可以争论,而且只是我非常偏颇的观点,但是我认为我不得不说避免这种不必要的争论。

我知道什么是保守/跟踪/世代/增量/并行/实时GC,以及它们的不同之处。我想大多数读者也已经知道这一点。我也同意GC在某些领域非常好,并且在某些情况下也显示出高吞吐量。

无论如何,我怀疑GC吞吐量始终比RC好。RC的大部分开销来自引用计数操作和锁定以保护引用计数编号变量。RC实施通常提供避免计数操作的方法。在Objective-C中,有__unsafe_unretained和在Swift中(尽管对我来说尚不清楚)unowned。如果引用计数操作成本不可接受,您可以尝试使用机制来选择性地选择退出。从理论上讲,我们可以非常积极地使用非保留引用来避免RC开销,从而可以模拟几乎唯一所有权的情况。另外,我希望编译器可以自动消除一些明显的不必要的RC操作。

与RC系统和AFAIK不同,GC系统不选择部分退出引用类型

我知道有许多已发布的图形和游戏正在使用基于GC的系统,并且还知道其中大多数都缺乏确定性。不仅针对性能特征,还针对对象寿命管理。Unity主要是用C ++编写的,但是很小的C#部分会引起所有奇怪的性能问题。HTML混合应用程序,仍然在任何系统上都遭受无法预料的峰值。广泛使用并不意味着它优越。这仅意味着对没有太多选择的人来说很容易并且很受欢迎。

更新2

再次为避免不必要的争论或讨论,我添加了更多详细信息。

@Asik提供了有关GC峰值的有趣观点。那就是我们可以将“ 无处不在的价值类型”方法视为退出GC的一种方法。这非常吸引人,甚至在某些系统上也可行(例如,纯功能方法)。我同意这在理论上是不错的。但实际上,它存在几个问题。最大的问题是此技巧的部分应用无法提供真正的无尖峰特性。

因为延迟问题始终是全有或全无的问题。如果一帧尖峰持续10秒(= 600帧),则整个系统显然将出现故障。这与好坏无关。它只是通过或失败。(或小于0.0001%)那么GC尖峰的来源在哪里?这是GC负载的不良分配。那是因为GC从根本上是不确定的。如果您进行任何垃圾处理,它将激活GC,并最终导致峰值。当然,在理想的世界中,GC负载永远是理想的,这不会发生,但是我生活在现实世界中,而不是想象中的理想世界。

然后,如果要避免峰值,则​​必须从整个系统中删除所有ref类型。但是,由于诸如.NET核心系统和库之类的不可移动部分,这非常困难,疯狂,甚至不可能。仅使用非GC系统要容易得多

与GC不同,RC从根本上讲是确定性的,您不必为了避免峰值而使用这种疯狂的优化(仅纯值类型)。您要做的是跟踪并优化导致尖峰的零件。在RC系统中,峰值是本地算法问题,但在GC系统中,峰值始终是全局系统问题。

我认为我的回答太离题了,大部分只是重复现有讨论。如果您真的想声称自己具有某些优势/劣势/替代品或其他任何关于GC / RC的东西,则该站点和StackOverflow上已有很多讨论,您可以在那继续战斗。


4
垃圾收集,尤其是世代收集,通常比参考计数要快得多
Jan Hudec 2014年

9
@JanHudec 在实时图形领域中,您的显着提高毫无意义。这就是为什么我提到GC需要巨大的飞跃。从理论上和实践上,世代GC甚至都没有达到无峰值的目的。
Eonil 2014年

5
更快和无尖峰是完全正交的类别。分代垃圾收集器速度更快。它们不是无钉的。
Jan Hudec

4
您所说的是吞吐量更快一直是一个模糊的术语,在上下文中可能有任何含义。如果要争论术语的含义,则应使用更精确的术语,而不要使用更快的术语,尤其是考虑到当前上下文-实时图形。
Eonil 2014年

11
@JanHudec:在移动设备或任何资源受限的设备上,GC的运行速度没有显着提高,这实际上是问题的主要部分。
梅森惠勒2014年

72

该语言比python快3.9倍,该语言一直在很大程度上失去大多数基准测试(好吧,它与Perl,Ruby和PHP相当;但是它输给了任何静态类型的东西),这无可厚非。

基准测试游戏显示C ++程序,除量级超过Python程序在大多数情况下更快。与Java,C#(在Mono上),OCaml,Haskell甚至不是静态类型的Clojure进行比较时,它并不是更好。

因此,真正的问题是,Objective-C如何仅比python快2.8倍。显然,他们谨慎地选择了基准,而ObjC的缓慢,完全动态的调度会带来很多伤害。任何静态类型的语言都应该能够做得更好。在复杂的对象排序中,有许多方法需要比较对象,而实际的比较本身可能并不十分复杂。因此,如果Swift至少利用了类型信息的某些优势,则可以轻松地在方法调用上做得更好,并且没有足够的其他操作可以使ObjC更好。

当然,正如基准测试游戏清楚地表明的那样,在不同任务上的相对性能差异很大,因此一个基准测试并不是真正具有代表性的。如果他们在基准测试中具有更大的优势,那么他们会向我们展示一个基准,因此在其他任务上可能并没有更好,或者没有太多。


13
我不太明白这个答案的重点。您是否在说“基准有缺陷”以回答“速度更快”?这就是您要说的重点吗?我看不出这是如何回答被问到的。
Bryan Oakley 2014年

15
@BryanOakley:我不认为基准存在缺陷,但是必须考虑是否有可能选择Swift更快的基准。
2014年

23
答案可能是“ Swift如何更快?” 可能是“实际上不是”,@ BryanOakley; 这就是我从简的答案中得到的要点。毕竟是“谎言,该死的谎言和统计数据”。
Josh Caswell 2014年

4
前阵子我们基准代号一个在iOS上运行,我们的Java实现比快得多的Objective-C codenameone.com/blog/...扬是正确的,动态调度实在是太慢了,如果他们提高他们哪怕是一点点,然后一些基准将显示出巨大的进步。如果他们将ARC改善了一点(由于更好的代码分析),那么它们可以摆脱大量的复杂性。语言越受限制,编译器就越能优化(参见Java),并且Swift增加了限制。
Shai Almog 2014年

7
Jan的答案是第一季度甚至第二季度的完美答案。当我将营销活动的基准视为主题演讲时,我想到:“哇,在最佳情况下只有1,3倍。我们的平均结果是什么?0.3倍?”
2014年

5

Objective-C动态分派每个方法调用。

假设:基准测试使用静态类型来让Swift编译器提升compare方法查找的sort循环力。这需要一个狭窄的类型限制,该限制仅允许数组中的Complex对象,而不允许Complex的子类。

(在Objective-C中,您可以根据需要手动调用方法查找,方法是调用语言运行时支持以查找方法指针。您最好确保数组中的所有实例都属于同一类)

假设: Swift会优化循环外的引用计数调用。

假设: Swift基准测试使用Complex结构代替Objective-C对象,因此排序比较不需要动态方法分派(因为它不能被子类化)或引用计数工作(因为它是值类型)。

(在Objective-C中,只要不涉及Objective-C对象(例如,对结构的C数组进行排序),就可以依靠C / C ++来提高性能。)


3

老实说,除非他们将源代码发布到他们正在使用的测试中,否则我将不相信Apple在此问题上要说的任何话。请记住,这是一家基于电源问题而从PPC转到Intel的公司,六个月前他们曾说Intel在商业中吸吮并实际折磨了Intel兔子。我想看到无可辩驳的确凿证据,证明Swift在更多类别中比在排序方面比ObjC更快。

另外,您必须质疑WWDC上发布的任何统计信息,因为它们充满了行销的味道。

话虽这么说,我自己还没有在swift和ObjC之间运行任何测试,但是据我所知,swift具有自己的LLVM IR扩展,并且可能在编译时比ObjC进行更多的优化。

全面披露:我正在编写位于https://ind.ie/phoenix/的开源Swift编译器

如果有人想帮助确保Swift不仅可以在Apple硬件上使用,请告诉我,我很乐意将您包括在内。


2
这读起来更像是一条冗长的评论,请参阅“ 如何回答
gna2015年

2
现在好点了吗?:)
greg.casamento 2015年

0

我在Swift教程中苦苦挣扎,在我看来Swift比Objective-C更加扎实(让我想到了Visual Basic),其“对象化”更少。如果他们考虑到C或C ++,我想后者会赢,因为它们甚至只有更多的编译时间。

在这种情况下,我认为Objective-C是其面向对象的纯度(和开销)的受害者。


13
在诸如C之类的没有对象本机实现的语言中,进行“复杂对象排序”基准将有些困难。鉴于本次演讲的受众可能是100%的Objective-C程序员,因此与C ++之类的语言进行比较也没有太大意义。快速的目的不是“嘿,这是有史以来最伟大的语言!” 而是“嘿,这比您现在用于OSX / iOS开发的语言要快”。
Bryan Oakley 2014年

10
C具有很好的性能qsort,可以进行复杂的对象排序;它只使用一个回调,该回调可以理解手头的对象。我怀疑缺少C ++,因为这std::sort会使Swift感到尴尬。(由于它是模板,因此C ++编译器可以对其进行大量优化,直至循环展开。)
MSalters 2014年

@MSalters:我完全同意你的看法。C和C ++都具有超越Swift的功能。是否有可能获得执行的测试。我更愿意用斯威夫特的Objective-C,C ++和C执行相同的标杆更多
涂成黑色的

@BryanOakley也说:“这种语言需要较少的方括号!”
尼克·贝德福德

1
这个答案根本无法解决,并且令人误解。OO并不是真的很慢,实际上,您会发现最快的系统将是C ++,Java和C#,并且编程的样式(无论是否为OO)都与最终的速度无关,除非您真的错误的代码。
比尔K
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.