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



关于一个使用RC4加密算法进行性能比较。

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


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


评论

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

与Python的比较才是真正的难题。

@syrion营销,该语言似乎是从python的语法中借用的(很像golang)。他们试图说“嘿,Python开发人员,您可以在Mac上写一些不太陌生的东西,它的速度要比目标C快得多,甚至快到您从未真正掌握过的目标”
@MichaelT我明白了,但还是很奇怪。任何对语言一无所知的人都会意识到,Python作为一种解释型语言,根本不会与Objective-C或其他编译语言(对于大多数任务)处于同一水平。用它作为基准很奇怪。

它们可能意味着编写代码所花费的时间...

#1 楼

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


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负载永远是理想的,这不会发生,但是我生活在现实世界中,而不是想象中的理想世界。

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

与GC不同,RC从根本上是确定性的,您不必仅使用这种疯狂的优化(仅纯值类型)来避免穗。您要做的是跟踪并优化导致尖峰的零件。在RC系统中,峰值是本地算法问题,但是在GC系统中,峰值始终是全局系统问题。如果您真的想声称自己具有某些优势/劣势/替代品或其他方面的GC / RC东西,则此站点和StackOverflow上已有很多讨论,您可以在那继续战斗。

评论


垃圾收集,尤其是世代收集,通常比引用计数要快得多。

– Jan Hudec
2014年6月5日在16:33

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

– Eonil
2014年6月5日在21:37

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

– Jan Hudec
2014年6月5日在21:46

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

– Eonil
2014年6月5日在22:32



@JanHudec:在移动设备或任何资源受限的设备上,GC的运行速度并没有明显提高,这实际上是问题的主要部分。

–梅森·惠勒
2014年6月14日13:18

#2 楼

这种语言比python快3.9倍,因此一贯丧失大多数基准测试的语言相当可观(好吧,它与Perl,Ruby和PHP相当;但是它却输给了任何静态类型的东西),这无可厚非。 >
基准测试游戏显示,在大多数情况下,C ++程序比python程序快几个数量级。与Java,C#(在Mono上),OCaml,Haskell甚至不是静态类型的Clojure进行比较时,它并没有更好。

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

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

评论


我不太明白这个答案的重点。您是否在说“基准有缺陷”以回答“速度更快”?这就是您要说的重点吗?我看不出如何回答所要求的。

–布莱恩·奥克利(Bryan Oakley)
2014年6月3日,11:57

@BryanOakley:我认为基准测试没有缺陷,但是必须考虑是否有可能选择Swift更快的基准测试。

– Jan Hudec
2014年6月3日,12:18

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

–jscs
2014年6月3日19:51



前一段时间,我们对在iOS上运行的Codename One进行了基准测试,并且我们的Java实现比Objective-C codenameone.com/blog/快得多。显示出巨大的进步。如果他们将ARC提高了一点点(由于进行了更好的代码分析),那么它们可以摆脱大量的复杂性。语言越受限制,编译器就越能优化(见Java),Swift增加了限制。

– Shai Almog
2014年6月4日下午5:34

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

–阿明·内格姆·阿瓦德(Amin Negm-Awad)
2014年6月9日8:30

#3 楼

假设:Objective-C动态分配每个方法调用。

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

(在Objective-C中,如果您确实愿意,可以通过调用语言运行时支持,以查找方法指针。您最好确保数组中的所有实例都属于同一类。)假设:Swift会优化循环外的引用计数调用假设:Swift基准测试使用Complex结构代替Objective-C对象,因此排序比较不需要动态方法分派(因为它不能被子类化)或引用计数工作(因为它是一种值类型)。

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

#4 楼

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

所有这些,我自己还没有在swift和ObjC之间进行任何测试,但是据我所知,swift具有自己的LLVM IR扩展,有可能正在做更多优化

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

,如果有人愿意的话为确保Swift不仅适用于Apple硬件,请告诉我,我很乐意包括您。

评论


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

– gna
2015年1月5日,0:11



现在好点了吗? :)

– greg.casamento
2015年1月5日,0:16

#5 楼

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

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

评论


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

–布莱恩·奥克利(Bryan Oakley)
2014年6月3日12:00

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

– MSalters
2014年6月4日上午10:46

@MSalters:我完全同意你的看法。 C和C ++都具有超越Swift的功能。是否有可能获得执行的测试。我非常愿意使用Swift,Objective-C,C ++和C执行相同的基准测试。

–涂成黑色
2014年6月4日在21:07



@BryanOakley也说:“这种语言需要较少的方括号!”

–尼克·贝德福德(Nick Bedford)
2014年6月20日在2:57

这个答案根本无法解决,并且令人误解。 OO并不是真的很慢,实际上,您会发现最快的系统将是C ++,Java和C#,并且编程的样式(无论是否为OO)都与最终的速度无关,除非您真的错误的代码。

– Bill K
2014年11月14日下午2:43