用高斯公式优化 Swift 代码,让运行速度飞跃数十万倍!

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

在开发过程中,我们始终在寻找优化代码的方法。有的时候,最强大的优化来自于看似简单的方法。

今天我们探索一个 19 世纪数学家的故事------卡尔·弗里德里希·高斯(Carl Friedrich Gauss),以及如何通过他的一个简单的算术公式显著提升 Swift 算法的性能。

高斯公式的魅力

我们先提一个需求:假设你需要计算从 1 到 n 的所有整数之和。

这是一个经典问题,并且有多种解决方法。为了演示,我编写了三个 Swift 函数来完成这一任务:

  1. For-In 循环

这是最直接的方法。通过迭代每个数字并累加,得到结果。

kotlin 复制代码
func sumUsingForIn(n: Int) -> Int {
    var sum = 0
    for i in 1...n {
        sum += i
    }
    return sum
}
  1. Reduce 方法

Swift 的函数式编程特性允许我们使用 reduce 方法来对范围内的数字求和。

kotlin 复制代码
func sumUsingReduce(n: Int) -> Int {
    return (1...n).reduce(0, +)
}
  1. 高斯公式

终于到了我们的重头戏------高斯公式

年少的高斯聪明地发现从 1 到 n 的总和可以通过一个简单的等式来计算。在 Swift 中,这可以用如下方式表达:

kotlin 复制代码
func sumUsingGauss(n: Int) -> Int {
    return n * (n + 1) / 2
}

即:

性能测试

为了测量这些方法的速度,我使用了 Swift 的 DispatchTime API来记录 n 为 1,000,000 时的执行时间(单位:毫秒)。

vbscript 复制代码
import Foundation

func measureExecutionTime(for function: (Int) -> Int, with n: Int) {
    let start = DispatchTime.now()
    _ = function(n)
    let end = DispatchTime.now()
    let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
    let timeInterval = Double(nanoTime) / 1_000_000// 转换为毫秒
    print("Execution time: \(timeInterval) ms")
}

// 测试每个函数
measureExecutionTime(for: sumUsingForIn, with: 1_000_000)
measureExecutionTime(for: sumUsingReduce, with: 1_000_000)
measureExecutionTime(for: sumUsingGauss, with: 1_000_000)

大家可以自行运行上面的代码,看看结果。我这里的结果为:

yaml 复制代码
Execution time: 2976.284459 ms
Execution time: 168.619834 ms
Execution time: 0.019208 ms

谁是最快的?

在进入性能对比之前,我们需要了解一下 Big-O表示法 ------这一计算机科学的基本概念帮助我们评估算法的效率。

Big-O表示法描述了算法执行时间(或空间占用)如何随着输入规模的变化而增长。它以_n_为单位表示,其中_n_代表输入数据的大小。

例如:

  • O(1): 常数时间,算法性能与_n_无关。

  • O(n): 线性时间,执行时间随_n_线性增长。

  • O(n²): 平方时间,执行时间随_n_成平方增长。

理解 Big-O 至关重要,因为它帮助我们预测算法在输入规模扩大时的表现,从而更容易地为给定问题选择最有效的解决方案。

回到我们的对比,三种方法的 Big-O 分析如下:

  • For-In 循环 :每个数字都被单独处理,因此时间复杂度为O(n)。对于大的_n_,执行时间线性增长。

  • Reduce 方法 :尽管使用了函数式编程,但内部同样要遍历范围,复杂度同为O(n)

  • 高斯公式 :绝对的赢家。凭借其常数时间复杂度O(1),无论_n_的大小,它都能直接通过单个算术操作计算总和。

对于 n 为 1,000,000 的情况,这种差别显而易见。For-In 循环最慢,Reduce 方法在 swift 内部应该是被优化过的,而高斯公式只需 0.02 毫秒。

通过采用更聪明的算法,我们不仅可以实现更好的性能,还能提升可扩展性,使得高斯公式成为求和序列或类似问题的理想解决方案。

通过高斯公式,函数运行速度提升了几十万倍。

在实际应用中使用

让我们从理论转向实践,其实如果你注意观察,代码中很多场景适合使用高斯公式。

比如一个游戏应用,玩家在通过关卡时累积得分。为了显示排行榜,需要计算直到某一关卡 n 的总得分。

如下是我用于解决此问题的三种方法:

  1. 循环实现(基础方法)

通过迭代累加得分。

swift 复制代码
func cumulativeScoreLoop(scores: [Int], upto level: Int) -> Int {
    var total = 0
    for i in 0..<min(level, scores.count) {
        total += scores[i]
    }
    return total
}
  1. Reduce实现(函数式方法)

使用Swift的 reduce 进行求和。

swift 复制代码
func cumulativeScoreReduce(scores: [Int], upto level: Int) -> Int {
    return scores.prefix(level).reduce(0, +)
}
  1. 高斯公式实现(优化方法)

如果得分可以预测(如1, 2, 3, ...),我们可以直接计算总得分。

swift 复制代码
func cumulativeScoreGaussFormula(upto level: Int) -> Int {
    return (level * (level + 1)) / 2
}

结论

高斯公式的故事提醒我们,优化不一定要复杂。通过简单的数学原理,我们可以显著提升代码性能。希望这个故事能激励你在日常编程中寻找类似的优化机会。

欢迎在评论区分享你的看法或提出问题,让我们共同探索更多优化应用的可能性!

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
HarderCoder19 小时前
深入理解 SwiftUI 中的 `@Observable` 与 `@Bindable`:从原理到实践
swiftui·swift
00后程序员张21 小时前
iOS 26 系统流畅度深度剖析,Liquid Glass 视效与界面滑动的实际测评
android·macos·ios·小程序·uni-app·cocoa·iphone
猪哥帅过吴彦祖21 小时前
Flutter 系列教程:布局基础 (下) - Stack 绝对定位和 Expanded 弹性布局
前端·flutter·ios
2501_915921431 天前
uWSGI + HTTPS 实战指南,配置、证书、TLS 终止与调试全流程(适用于生产与真机抓包排查)
网络协议·http·ios·小程序·https·uni-app·iphone
2501_916008891 天前
iOS 26 系统流畅度剖析:Liquid Glass 动画表现 + 用户反馈
android·macos·ios·小程序·uni-app·cocoa·iphone
2501_915909061 天前
Python 爬虫 HTTPS 实战,requests httpx aiohttp 抓取技巧、证书问题与抓包调试全流程
爬虫·python·ios·小程序·https·uni-app·iphone
00后程序员张2 天前
iOS 开发环境搭建完整指南 Xcode 安装配置、iOS 开发工具选择、ipa 打包与 App Store 上架实战经验
android·macos·ios·小程序·uni-app·iphone·xcode
折七2 天前
expo sdk53+ 集成极光推送消息推送 ios swift
前端·javascript·ios
猪哥帅过吴彦祖2 天前
Flutter 系列教程:布局基础 (上) - `Container`, `Row`, `Column`, `Flex`
前端·flutter·ios
90后的晨仔2 天前
xcode 16 删除 Provisioning Profiles 文件的有效路径
ios