【问题标题】:Swift vs Objective-C Fibonacci Sequence Speed ComparisonSwift 与 Objective-C 斐波那契数列速度比较
【发布时间】:2015-01-27 00:16:02
【问题描述】:

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

我刚刚用 Swift 和 Objective-C 编写了一个简单的递归斐波那契序列程序。

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

Objective-C 结果:

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

Swift 结果

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

现在,我什至在所有 Swift 编译器优化级别(用于调试)中运行了 Swift 版本,即无、最快、最快未选中。我还将代码生成优化级别设置为无,快速....最快的积极优化。 然而,所有 Swift 结果都接近 0.6 毫秒

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

欢迎和感谢任何建议或 cmets ! ^^!

Objective-C 版本

-(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)");

【问题讨论】:

  • 你如何测量时间?
  • @BryanChen 我刚刚用时间测量代码更新了这个问题,我在 Swift 和 Objective-C 中都使用 NSDate
  • NSDate 不适合基准测试。并且 >1 ms 太小了,您最好重复测试多次,这样它们都至少需要一秒钟才能运行。此外,您的代码只会显示动态调度与静态调度之间的区别。
  • (除此之外,您的方法:3,作为参数,给出 2;5 给出 5;8 给出 21。您应该得到的结果的解释是什么?)
  • @BryanChen 实际上,我在 Swift 和 Objective-C 上分别重复了超过 15 次实验,我得到了相似的结果。

标签: ios objective-c xcode swift


【解决方案1】:

在决定两种编程语言中哪一种更快时需要考虑很多事情。我在 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() 函数。

【讨论】:

  • 很好的例子。顺便说一下,这个洗牌是not even distributed。更好的是,使用let randomIndex = Int(arc4random_uniform(UInt32(count - i))) + i。
  • 感谢您的提示!本质上,我的非通用实现采用[Int] 而不是[T]。您可以使用基准here 查看我的不同实现。 [Int] 实现也比 NSMutableArray 版本快。只要您能够使用 struct 对象,我确信您知道 Int 和 String 是的,性能改进就会发生。使用 struct 对象的缺点是您无法将它们桥接到 Objective-C。据我所知,Int 和 String 是唯一可以桥接到 Objective-C 的结构体。
  • @fyell 仅供参考:我使用最新的 Xcode beta 版本 6.3 (6D532l) 尝试了代码,它在 0.04 秒内完成(通用版本,100 万整数,发布版本,目标 OS X)。 Swift 仍在积极改进中,与 Objective C 的比较也在继续改进,有时甚至是显着的。
  • @MirekE 它在测试版中当然要快得多! Swift 性能的提升给我留下了深刻的印象。查看我的博客文章以及我的一些 Swift 1.2 基准测试medium.com/@fielgood/…
【解决方案2】:

选择斐波那契作为基准有点讽刺,因为在 WWDC 2014 视频Advanced Swift 中,他们使用斐波那契序列作为示例,说明如何编写一个速度快几个数量级的通用 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 递归斐波那契函数进行比较是不公平的,因为这会使它尘埃落定。我什至不确定我是否同意 WWDC 关于 Swift 通用 memoize 实现的优点的所有结论。但性能提升令人吃惊。


在很多模式中,对 Objective-C 代码的幼稚翻译会导致 Swift 实现速度变慢。特别是,比你的 Swift 代码慢一点的例子更具戏剧性,我被一些简单的情况吓到了,在这些情况下,用 Swift 编写一个在逻辑上看起来非常相似(甚至更优雅)的例程很容易,但是确实慢得多(或者至少在应用程序开发人员重构 Swift 实现之前)。

归根结底,我个人会犹豫得出任何简单的结论,即 Swift 比 Objective-C 更快,反之亦然。我怀疑在某些算法/应用程序中 Swift 更快,而另一些则不是。

此外,您说关于编程语言的选择,您“希望选择更快/更好的语言”。我会争辩说“更快”的语言总是“更好”的语言(否则,我们都还在编写汇编代码)。通常,语言的选择不是代码的原始计算效率,而是开发人员的效率。我们都应该选择可以编写最健壮代码的语言,以最具成本效益的方式编写代码,编写将来最容易维护的代码,并提供最优质的用户体验。

该语言是 Swift 还是 Objective-C 是一个见仁见智的问题,不适合这个论坛。

【讨论】:

  • +1 Esp 最后两段。在当今,性能并不是应用程序开发的大问题。如果是这样,则更多的是结构问题而不是单个计算。
  • 您写过关于非优化函数的文章,您是否知道一些可以学习如何改进编码的好资源?这么多专业的东西,没有简单的初学者教程
  • 那时,我认为您已经走出了简单的网络教程领域,进入了深入研究算法理论和设计领域的大学课程和教科书的世界。我刚刚在亚马逊的书中搜索了“算法”,顶部有一堆很有前途的文本。我倾向于得到一个平衡理论(例如“大哦”表示法、NP 完全问题等)与更实际的考虑(例如不同排序算法的分析和比较、哈希和缓存等优化技术等)的理论。 )。
【解决方案3】:

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

【讨论】:

  • OP 想看看 Swift 其实更快。这没有回答问题。
  • 什么意思? OP 目前正在测试一种特定的方法,并试图概括整个语言的性能。除了哪种语言能够更快地计算斐波那契数列之外,还有很多其他因素应该影响这个决定。这就像试图挑选最好的足球运动员,只看他们的 40 岁。
猜你喜欢
  • 2021-02-14
  • 2020-06-06
  • 2015-06-05
  • 1970-01-01
  • 2021-11-30
  • 2019-04-06
  • 2015-07-05
相关资源
最近更新 更多