在swift中测量时间的正确方法

问题描述 投票:0回答:1

我正在使用几种语言,我想比较执行一些计算所需的时间。我在swift中进行适当的时间测量时遇到了麻烦。我正在尝试从this answer解决方案,但是我得到了不正确的结果 - 当我运行swift code.swift时,编辑需要的时间比编译后的时间长得多,结果告诉我相反的结果:

 $  swiftc sort.swift -o csort
 gonczor  ~  Projects  Learning  Swift  timers 
 $  ./csort 
 Swift:  27858 ns
 gonczor  ~  Projects  Learning  Swift  timers 
 $  swift sort.swift 
 Swift:  22467 ns

这是代码:

iimport Dispatch
import CoreFoundation

var data = [some random integers]


func sort(data: inout [Int]){
    for i in 0..<data.count{
        for j in i..<data.count{
            if data[i] > data[j]{
                let tmp = data[i]
                data[i] = data[j]
                data[j] = tmp
            }
        }
    }
}

// let start = DispatchTime.now()
// sort(data: &data)
// let stop = DispatchTime.now()
// let nanoTime = stop.uptimeNanoseconds - start.uptimeNanoseconds
// let nanoTimeDouble = Double(nanoTime) / 1_000_000_000
let startTime = clock()
sort(data: &data)
let endTime = clock()
print("Swift:\t \(endTime - startTime) ns")

当我将计时器更改为clock()调用或使用CFAbsoluteTimeGetCurrent()以及我是否比较1000或5000元素数组时,也会发生同样的情况。

编辑:

更清楚。我知道粘贴一次运行并不会产生具有统计意义的结果,但问题是我看到一种方法比另一种方法花费的时间要长得多,而且我被告知有些不同的方法。

EDIT2:我似乎还没有表达我的问题。我创建了一个bash脚本来显示问题。

我正在使用time实用程序来检查执行命令所需的时间。再一次:我只是鬼混,我不需要具有统计意义的结果。我只是想知道为什么swift实用程序告诉我一些与我不同的东西。

脚本:

#!/bin/bash

echo "swift sort.swift"
time swift sort.swift

echo "./cswift"
time ./csort

结果:

$  ./test.sh 
swift sort.swift
Swift:   22651 ns

real    0m0.954s
user    0m0.845s
sys 0m0.098s
./cswift
Swift:   25388 ns

real    0m0.046s
user    0m0.033s
sys 0m0.008s

你可以看到使用time的结果表明,执行一个命令所需的时间比另一个命令多10倍。从快速的代码我得到的信息,它或多或少相同。

swift
1个回答
1
投票

几点意见:

  1. 就测量速度的最佳方法而言,你可以使用DateCFAbsoluteTimeGetCurrent,但你会看到那些the documentation会警告你 重复调用此函数并不能保证单调增加结果。 这有效地警告您,如果在中间期间对系统时钟进行调整,则计算的经过时间可能不完全准确。 如果在测量经过的时间时需要很高的准确度,建议使用mach_time。这涉及一些恼人的CPU特定调整(参见Technical Q&A 1398。),但CACurrentMediaTime提供了一个简单的替代方案,因为它使用mach_time(不会遇到此问题),但将其转换为秒,以使其非常易于使用。
  2. 尽管如此,似乎在这里有一个更基本的问题:看起来你正试图调和运行Swift代码的不同方式之间的区别,即: swiftc hello.swift -o hello time ./hello time swift hello.swift 前者正在将hello.swift编译成独立的可执行文件。后者正在加载swift REPL,然后有效地解释Swift代码。 这与测量时间的“正确”方法无关。执行预编译版本的时间应始终比调用swift并将其传递给源文件更快。调用后者不仅有更多的开销,而且一旦执行开始,预编译版本的执行可能会更快。
  3. 如果您真的对运行这些例程的性能进行基准测试,那么您不应该依赖于单个5000项。我建议对数百万个项目进行排序并重复多次,并统计统计数据。这种排序的单次迭代不足以得出任何有意义的结论。

最重要的是,您需要决定是否要仅对代码的执行进行基准测试,还要确定启动REPL的开销。

© www.soinside.com 2019 - 2024. All rights reserved.