Swift——如何测量一个函数/功能的运行时间

当需要测试程序的性能时,Xcode 自带的测试功能有时并不能满足我们的需要,这个时候就需要自己编写测试代码。测试性能主要是测试程序或代码运行时间,不论是测试 CPU/GPU 密集型程序,还是读写密集型程序,都需要获取程序或函数的运行时间来计算性能。

如果是测试 CLI(Command Line Interface,命令行交互)程序,那么就可以在使用程序时,加上time命令,就可以获取整个程序的运行时间。但是如果想测试程序代码中的某一个函数运行时间,或者测试 GUI 程序的时候,这种方法就行不通了。我们需要在代码中加上一个“计时器”,去自己安排测量工作。

在 Swift 中实现这种测量有两种方法,第一个是比较方便但是只能在新系统上用,第二个兼容性比较好但是不安全(精确度稍差,但是可以忽略)。

新系统上的简易方法measure

不过苹果在 iOS 16、macOS 13 开始,新增了的数据结构ClockContinuousClock,都有一个方法叫measure,可以用来测试一个函数的运行时间。

measure官方文档

使用起来也非常简单。

首先,实例一个ContinuousClock

let clock = ContinuousClock()

然后再使用以下语句即可获取某个函数的运行时间:

let elapsed = clock.measure {
    
    
	someWork()
}

这里需要注意,let是强制使用的,不能前面声明一个变量,然后在这实例化。

这里获得的elapsedContinuousClock.Instant.Duration类型的,需要转化成字符串使用,转化方法如下:

var duration: String = ""
let elapsed = clock.measure {
    
    
	quicksort()
}
//elapsed.description是字符串类型
duration = elapsed.description

总体代码为:

struct ContentView: View {
    
    
    var clock = ContinuousClock()
    @State private var duration: String = ""
    var body: some View {
    
    
        VStack {
    
    
            Text("点击按钮进行快速排序测试:")
                .padding()
                
            Button(action: {
    
    
            	//获取时间间隔,也就是运行时间
                let elapsed = clock.measure {
    
    
                	//测试函数为‘quicksort’
                	quicksort()
                }
                //把获取到的时间间隔转换成字符串
                duration = elapsed.description
            }) {
    
    
                Text("Start")
            }
            .padding()

			// 显示时间,由于elapsed.description最后自带字符串“second”,所以不用加单位
            Text("消耗时间为:\(duration)")
                .padding()
        }
        .padding()
    }
}

下面是在 App 中运行的情况:

在 App 中运行的情况

通用方法

如果不是最新的系统,或者是想自己写相关的方法函数,那么就可以使用经典办法:时间差。记录开始的时间和终止的时间,再做差即可获得运行时间。

那么这个时间以什么为准呢?C 语言是时钟时间,但是 Swift 从 iOS 16 开始才有时钟时间,之前只有Date类型。好在 Date 就可以实现我们的目的,使用其中的timeIntervalSince1970值即可。

timeIntervalSince1970这个值是非常有历史含义的一个值,所有的系统(不光是苹果的系统)都有这个值,因为 1970 是第一个大范围使用的系统 Unix 的起始时间,而timeIntervalSince1970记录的是从 1970-01-01 00:00:00 开始,到此时此刻过去的时间,精度可以到达小数点到达毫秒(甚至更小,与上一种方法精度差不多)。

由于和上一个方法只有一部分不同,所以直接列出整体代码:

struct ContentView: View {
    
    
    @State private var duration: String = ""
    var body: some View {
    
    
        VStack {
    
    
            Text("点击按钮进行快速排序测试:")
                .padding()
            Button(action: {
    
    
            	//记录开始时间
                let start_time = Date().timeIntervalSince1970
                //开始运行被测试函数
                quicksort()
                //记录结束时间
                let end_time = Date().timeIntervalSince1970
                //做差获取间隔时间,并且将其变成字符串格式
                duration = TimeInterval(end_time-start_time).description
            }) {
    
    
                Text("Start")
            }
            .padding()

			//由于这个方法没有带单位,所以自己加一个“seconds”
            Text("消耗时间为:\(duration) seconds")
                .padding()
        }
        .padding()
    }
}

运行效果和上一种方法一模一样,所以不列出了。

希望能帮到有需要的人~

猜你喜欢

转载自blog.csdn.net/qq_33919450/article/details/129916722