Swift与Objective-C Fibonacci序列速度比较

时间:2015-01-27 00:16:02

标签: ios objective-c xcode swift

我有问题。我想知道哪一个确实更快(Swift或Objective-C),因为当我开始开发应用程序时,我想选择更快/更好的一个。根据许多消息来源(例如Apple的WWDC或http://www.jessesquires.com/apples-to-apples-part-two/),Swift假设速度更快。

我刚刚在Swift和Objective-C中编写了一个简单的递归fibonacci序列程序。

然而,当我在模拟器上运行fib(35)时,我得到了惊人的结果:

Objective-C结果:

::: fib :::: 9227465 ::: duration ::: 0.122813秒

快速结果

::: fib :::: 9227465 ::: duration ::: 0.606831073760986秒

现在,我甚至在所有Swift编译器优化级别(用于调试)中运行Swift版本,这是None,Fastest,Fastest-Unchecked。我还将代码生成优化级别改为无,快速......最快的进取优化。 然而,所有Swift结果都接近0.6毫秒

现在我能想到的最后一件事可能是,我正在将Apple与Orange进行比较? 你们看到我在这里失踪的东西吗?还有什么我必须打开(除了Swfit编译器和Apple LLVM代码生成的优化级别)以使Swift程序运行得更快吗?

欢迎并赞赏任何建议或意见! ^^!

Objective-C Version

-(int)fib:(int)num{
    if (num == 0) {
        return 0;
    }
    if (num == 1) {
        return 1;
    }    
    return [self fib:num - 1] + [self fib:num - 2];
}

Swift版本

func fib(num: Int) -> Int{
    if(num == 0){
        return 0;
    }
    if(num == 1){
        return 1;
    }
    return fib(num - 1) + fib(num - 2);
}

Objective-C时间测量

  NSTimeInterval start = [[NSDate date] timeIntervalSince1970];
  int result = [self fib:35];
  NSTimeInterval end = [[NSDate date] timeIntervalSince1970];

  NSTimeInterval duration = end - start;
  NSLog(@":::fib::::%d:::duration:::%f",result,duration);

快速时间测量

var start = NSDate().timeIntervalSince1970;
let result = fib(35);
var end = NSDate().timeIntervalSince1970;

var duration = end - start;
println(":::fib::::\(result) :::duration:::\(duration)");

3 个答案:

答案 0 :(得分:7)

在决定哪两种编程语言更快时,需要考虑很多事情。我在Swift和Objective-C之间做了几个基准测试(https://github.com/vsco/swift-benchmarks),我发现在某些情况下Swift更快,而在其他情况下,Objective-C更快。例如,如果需要操作大量数据,在Swift中使用struct对象将提供巨大的性能提升。相比之下,使用非结构对象使得Swift明显慢于它的Objective-C对应物。

另外,如何使用Swift中的某些功能对于它的执行效果至关重要。以此功能为例:

class func shuffleGenericObjects<T>(inout array:[T]) {
    for (var i = 0; i < array.count; i++) {
        let currentObject: T = array[i]
        let randomIndex = Int(arc4random()) % array.count
        let randomObject: T = array[randomIndex]

        array[i] = randomObject;
        array[randomIndex] = currentObject
    }
}

当然,它最适合最小化重复代码,但当我执行此方法超过100万个Int对象时,大约需要32秒才能完成。与非通用实现相反,仅执行0.181秒。

我还建议不要在Swift中使用NSDate函数进行基准测试。我遇到了一些导致NSDate返回错误时间的错误。最好将基准置于XCTestCase并使用measureBlock()函数。

答案 1 :(得分:5)

选择Fibonacci作为您的基准有点讽刺,因为在WWDC 2014视频Advanced Swift中他们使用Fibonacci序列作为如何编写几个命令的通用memoize函数的示例更快。

func memoize<T: Hashable, U>(body: ((T)->U, T) -> U) -> (T)->U {
    var memo = [T: U]()
    var result: ((T)->U)!
    result = { x in
        if let q = memo[x] { return q }
        let r = body(result, x)
        memo[x] = r
        return r
    }
    return result
}

然后你可以:

let fib = memoize { fib, x in x < 2 ? x : fib(x - 1) + fib(x - 2) }

let result = fib(35)

现在,很明显,将它与非优化的Objective-C递归Fibonacci函数进行比较是不公平的,因为这会让它陷入困境。我甚至不确定我是否同意WWDC关于Swift通用memoize实现的优点的所有结论。但性能提升令人吃惊。


有很多模式,Objective-C代码的天真翻译会导致Swift实现速度变慢。特别是,比Swift代码稍微慢一点的例子要戏得多,我已经被简单的情况吓到了,在Swift中编写一个逻辑非常相似(甚至更优雅)的例程非常容易,但是实际上要慢得多(或至少在应用程序开发人员重构Swift实现之前)。

最重要的是,我个人不愿意得出Swift的任何简单结论都比Objective-C更快,反之亦然。我怀疑有一些算法/应用程序,其中Swift更快,而其他的则不是。

此外,你说关于编程语言的选择,你“想选择更快/更好的”。我认为“更快”的语言总是“更好”的(否则,我们仍然会编写汇编代码)。通常,语言的选择不是代码的原始计算效率,而是开发人员的有效性。我们都应该选择能够编写最强大代码的语言,以最具成本效益的方式进行编写,编写将来最容易维护的代码,并提供最佳的用户体验。

该语言是Swift还是Objective-C是一个意见问题,不适用于此论坛。

答案 2 :(得分:1)

您的代码看起来不错,但是您不能在这种情况下概括编程语言的快速性。在去年Apple的主题演讲中,他们表示Swift中的“复杂对象排序”更快。在Objective-C中可能有一些更快的东西,但一般来说,Swift应该是更快的语言。