tl; dr使用默认的发行优化级别[-O],在此基准下,Swift 1.0现在与C一样快。
这是Swift Beta中的就地快速排序:
func quicksort_swift(inout a:CInt[], start:Int, end:Int) { if (end - start < 2){ return } var p = a[start + (end - start)/2] var l = start var r = end - 1 while (l <= r){ if (a[l] < p){ l += 1 continue } if (a[r] > p){ r -= 1 continue } var t = a[l] a[l] = a[r] a[r] = t l += 1 r -= 1 } quicksort_swift(&a, start, r + 1) quicksort_swift(&a, r + 1, end)}和在C中相同:
void quicksort_c(int *a, int n) { if (n < 2) return; int p = a[n / 2]; int *l = a; int *r = a + n - 1; while (l <= r) { if (*l < p) { l++; continue; } if (*r > p) { r--; continue; } int t = *l; *l++ = *r; *r-- = t; } quicksort_c(a, r - a + 1); quicksort_c(l, a + n - l);}两种工作:
var a_swift:CInt[] = [0,5,2,8,1234,-1,2]var a_c:CInt[] = [0,5,2,8,1234,-1,2]quicksort_swift(&a_swift, 0, a_swift.count)quicksort_c(&a_c, CInt(a_c.count))// [-1, 0, 2, 2, 5, 8, 1234]// [-1, 0, 2, 2, 5, 8, 1234]
两者在与编写的相同的程序中调用。
var x_swift = CInt[](count: n, repeatedValue: 0)var x_c = CInt[](count: n, repeatedValue: 0)for var i = 0; i < n; ++i { x_swift[i] = CInt(random()) x_c[i] = CInt(random())}let swift_start:UInt64 = mach_absolute_time();quicksort_swift(&x_swift, 0, x_swift.count)let swift_stop:UInt64 = mach_absolute_time();let c_start:UInt64 = mach_absolute_time();quicksort_c(&x_c, CInt(x_c.count))let c_stop:UInt64 = mach_absolute_time();这会将绝对时间转换为秒:
static const uint64_t NANOS_PER_USEC = 1000ULL;static const uint64_t NANOS_PER_MSEC = 1000ULL * NANOS_PER_USEC;static const uint64_t NANOS_PER_SEC = 1000ULL * NANOS_PER_MSEC;mach_timebase_info_data_t timebase_info;uint64_t abs_to_nanos(uint64_t abs) { if ( timebase_info.denom == 0 ) { (void)mach_timebase_info(&timebase_info); } return abs * timebase_info.numer / timebase_info.denom;}double abs_to_seconds(uint64_t abs) { return abs_to_nanos(abs) / (double)NANOS_PER_SEC;}以下是编译器优化级别的摘要:
[-Onone] no optimizations, the default for debug.[-O] perform optimizations, the default for release.[-Ofast] perform optimizations and disable runtime overflow checks and runtime type checks.
时间与秒 [-Onone] 为 N = 10_000 :
Swift: 0.895296452C: 0.001223848
这是Swift的内置sort(),其 n = 10_000 :
Swift_builtin: 0.77865783
这是 [-O] , n = 10_000 :
Swift: 0.045478346C: 0.000784666Swift_builtin: 0.032513488
如您所见,Swift的性能提高了20倍。
根据mweathers的回答,设置 [-Ofast] 会带来真正的不同,导致这些时间为
n = 10_000 :
Swift: 0.000706745C: 0.000742374Swift_builtin: 0.000603576
对于 n = 1_000_000 :
Swift: 0.107111846C: 0.114957179Swift_sort: 0.092688548
为了比较,这是 [-Onone] 的 n = 1_000_000 :
Swift: 142.659763258C: 0.162065333Swift_sort: 114.095478272
因此,在开发的这个阶段,没有优化的Swift几乎比该基准测试中的C慢1000倍。另一方面,将两个编译器都设置为[-Ofast],即使实际上不比C稍好,Swift的实际效果也至少一样好。
已经指出,[-Ofast]更改了语言的语义,使其潜在地不安全。这是Apple在Xpre 5.0发行说明中指出的内容:
LLVM中提供了新的优化级别-
Ofast,可以进行积极的优化。-Ofast放宽了一些保守的限制,大多数情况下对于浮点运算是安全的,这对大多数代码来说都是安全的。它可以从编译器中获得明显的高性能优势。
他们全都主张。无论是不是明智,我都不能说,但是据我所知,如果您不进行高精度浮点运算并且您确信没有整数或整数,那么在发行版中使用[-Ofast]似乎足够合理。程序中可能发生数组溢出。如果您确实需要高性能
和 溢出检查/精确算术,请立即选择其他语言。
测试版3更新:
n = 10_000, 带有 [-O] :
Swift: 0.019697268C: 0.000718064Swift_sort: 0.002094721
Swift通常要快一些,看起来Swift的内置排序已经发生了很大变化。
最后更新:
[-Onone] :
Swift: 0.678056695C: 0.000973914
[-O] :
Swift: 0.001158492C: 0.001192406
[-Ounchecked] :
Swift: 0.000827764C: 0.001078914



