tl;dr Swift 1.0 is now as fast as C by this benchmark using the default release optimisation level [-O].
(tl; Dr Swift 1.0现在使用默认版本优化级别[-O]通过此基准测试与C一样快。)
Here is an in-place quicksort in Swift Beta:
(这是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)
}
And the same in C:
(在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);
}
Both work:
(两者都有效:)
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]
Both are called in the same program as written.
(两者都在与编写的程序中调用。)
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();
This converts the absolute times to seconds:
(这会将绝对时间转换为秒:)
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;
}
Here is a summary of the compiler's optimazation levels:
(以下是编译器优化级别的摘要:)
[-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.
Time in seconds with [-Onone] for n=10_000 :
(对于n = 10_000 , [-Onone]的时间以秒为单位 :)
Swift: 0.895296452
C: 0.001223848
Here is Swift's builtin sort() for n=10_000 :
(这是Swift的内置排序(),用于n = 10_000 :)
Swift_builtin: 0.77865783
Here is [-O] for n=10_000 :
(对于n = 10_000,这是[-O] :)
Swift: 0.045478346
C: 0.000784666
Swift_builtin: 0.032513488
As you can see, Swift's performance improved by a factor of 20.
(如您所见,Swift的性能提高了20倍。)
As per mweathers' answer , setting [-Ofast] makes the real difference, resulting in these times for n=10_000 :
(根据mweathers的回答 ,设置[-Ofast]会产生真正的差异,导致n = 10_000的这些时间:)
Swift: 0.000706745
C: 0.000742374
Swift_builtin: 0.000603576
And for n=1_000_000 :
(对于n = 1_000_000 :)
Swift: 0.107111846
C: 0.114957179
Swift_sort: 0.092688548
For comparison, this is with [-Onone] for n=1_000_000 :
(为了比较,对于n = 1_000_000 ,这是[-Onone] :)
Swift: 142.659763258
C: 0.162065333
Swift_sort: 114.095478272
So Swift with no optimizations was almost 1000x slower than C in this benchmark, at this stage in its development.
(因此,在这个基准测试中,没有优化的Swift在开发的这个阶段比C慢了近1000倍。)
On the other hand with both compilers set to [-Ofast] Swift actually performed at least as well if not slightly better than C. (另一方面,两个编译器都设置为[-Ofast] Swift实际上至少表现得好,如果不是比C略好一点。)
It has been pointed out that [-Ofast] changes the semantics of the language, making it potentially unsafe.
(已经指出[-Ofast]改变了语言的语义,使其可能不安全。)
This is what Apple states in the Xcode 5.0 release notes: (这就是Apple在Xcode 5.0发行说明中所说的:)
A new optimization level -Ofast, available in LLVM, enables aggressive optimizations.
(LLVM中提供的新优化级别-Ofast可实现积极的优化。)
-Ofast relaxes some conservative restrictions, mostly for floating-point operations, that are safe for most code. (-Ofast放松了一些保守的限制,主要用于浮点运算,对大多数代码都是安全的。)
It can yield significant high-performance wins from the compiler. (它可以从编译器中获得显着的高性能胜利。)
They all but advocate it.
(他们都提倡它。)
Whether that's wise or not I couldn't say, but from what I can tell it seems reasonable enough to use [-Ofast] in a release if you're not doing high-precision floating point arithmetic and you're confident no integer or array overflows are possible in your program. (这是否明智我不能说,但从我可以说的是,如果你没有进行高精度浮点运算并且你确信没有整数或者一个版本,那么在一个版本中使用[-Ofast]似乎是合理的。您的程序中可能存在数组溢出。)
If you do need high performance and overflow checks / precise arithmetic then choose another language for now. (如果您确实需要高性能和溢出检查/精确算术,那么现在就选择另一种语言。)
BETA 3 UPDATE:
(BETA 3更新:)
n=10_000 with [-O] :
(n = 10_000,带[ - O] :)
Swift: 0.019697268
C: 0.000718064
Swift_sort: 0.002094721
Swift in general is a bit faster and it looks like Swift's built-in sort has changed quite significantly.
(一般来说Swift有点快,看起来Swift的内置排序已经发生了很大变化。)
FINAL UPDATE:
(最终更新:)
[-Onone] :
([-Onone] :)
Swift: 0.678056695
C: 0.000973914
[-O] :
([-O] :)
Swift: 0.001158492
C: 0.001192406
[-Ounchecked] :
([-Ounchecked] :)
Swift: 0.000827764
C: 0.001078914