我正在使用几种语言,我想比较执行某些计算所需的时间。我在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次或更少。从快速的代码中我得到的信息或多或少相同。
答案 0 :(得分:1)
有几点意见:
就测量速度的最佳方式而言,您可以使用Date
或CFAbsoluteTimeGetCurrent
,但是您会看到the documentation会为您发出警告< / p>
重复调用此函数并不能保证单调增加结果。
这有效地警告您,如果在中间期间系统时钟有调整,计算的经过时间可能不完全准确。
如果在测量经过的时间时需要很高的准确度,建议使用mach_time
。这涉及一些恼人的CPU特定调整(请参阅Technical Q&A 1398。),但CACurrentMediaTime
提供了一个简单的替代方案,因为它使用mach_time
(不会遇到此问题),但将其转换为秒使它真的很容易使用。
尽管如此,似乎在这里有一个更基本的问题:看起来你正试图调和运行Swift代码的不同方式之间的区别,即:
swiftc hello.swift -o hello
time ./hello
和
time swift hello.swift
前者正在将hello.swift
编译成独立的可执行文件。后者加载swift
REPL,然后有效地解释Swift代码。
这与&#34;适当的&#34;无关。衡量时间的方法。执行预编译版本的时间应始终比调用swift
并将其传递给源文件更快。调用后者不仅有更多的开销,而且一旦执行开始,预编译版本的执行速度可能会更快。
如果您真的对运行这些例程的性能进行基准测试,则不应该依赖于单个5000项。我建议对数百万个项目进行排序并重复多次,并对统计数据求平均值。单一的迭代迭代不足以得出任何有意义的结论。
最重要的是,你需要决定是否只想对代码的执行进行基准测试,还要确定启动REPL的开销。