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

时间:2017-12-16 22:07:46

标签: swift

我正在使用几种语言,我想比较执行某些计算所需的时间。我在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次或更少。从快速的代码中我得到的信息或多或少相同。

1 个答案:

答案 0 :(得分:1)

有几点意见:

  1. 就测量速度的最佳方式而言,您可以使用DateCFAbsoluteTimeGetCurrent,但是您会看到the documentation会为您发出警告< / p>

      

    重复调用此函数并不能保证单调增加结果。

    这有效地警告您,如果在中间期间系统时钟有调整,计算的经过时间可能不完全准确。

    如果在测量经过的时间时需要很高的准确度,建议使用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代码。

    这与&#34;适当的&#34;无关。衡量时间的方法。执行预编译版本的时间应始终比调用swift并将其传递给源文件更快。调用后者不仅有更多的开销,而且一旦执行开始,预编译版本的执行速度可能会更快。

  3. 如果您真的对运行这些例程的性能进行基准测试,则不应该依赖于单个5000项。我建议对数百万个项目进行排序并重复多次,并对统计数据求平均值。单一的迭代迭代不足以得出任何有意义的结论。

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