3 回答

TA貢獻1851條經驗 獲得超5個贊
使用默認的發行優化級別[-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.895296452
C: 0.001223848
這是Swift的內置sort(),其n = 10_000:
Swift_builtin: 0.77865783
這是[-O],n = 10_000:
Swift: 0.045478346
C: 0.000784666
Swift_builtin: 0.032513488
如您所見,Swift的性能提高了20倍。
根據mweathers的回答,設置[-Ofast]會帶來真正的不同,導致這些時間為n = 10_000:
Swift: 0.000706745
C: 0.000742374
Swift_builtin: 0.000603576
對于n = 1_000_000:
Swift: 0.107111846
C: 0.114957179
Swift_sort: 0.092688548
為了比較,這是[-Onone]的n = 1_000_000:
Swift: 142.659763258
C: 0.162065333
Swift_sort: 114.095478272
因此,在開發的這個階段,沒有優化的Swift幾乎比該基準測試中的C慢1000倍。另一方面,將兩個編譯器都設置為[-Ofast],即使實際上不比C稍好,Swift的實際效果也至少一樣好。
已經指出,[-Ofast]更改了語言的語義,使其潛在地不安全。這就是Apple在Xcode 5.0發行說明中指出的內容:
LLVM中提供了新的優化級別-Ofast,可以進行積極的優化。-Ofast放寬了一些保守的限制,大多數情況下對于浮點運算來說是安全的,這對大多數代碼來說都是安全的。它可以從編譯器中獲得明顯的高性能優勢。
他們全都主張。無論是不是明智,我都不能說,但是據我所知,如果您不進行高精度浮點運算并且您確信沒有整數或整數,那么在發行版中使用[-Ofast]似乎足夠合理。程序中可能發生數組溢出。如果您確實需要高性能和溢出檢查/精確算術,請立即選擇另一種語言。
測試版3更新:
n = 10_000,帶有[-O]:
Swift: 0.019697268
C: 0.000718064
Swift_sort: 0.002094721
Swift通常要快一些,看起來Swift的內置排序已經發生了很大變化。
最后更新:
[-Onone]:
Swift: 0.678056695
C: 0.000973914
[-O]:
Swift: 0.001158492
C: 0.001192406
[-Ounchecked]:
Swift: 0.000827764
C: 0.001078914

TA貢獻1966條經驗 獲得超4個贊
我決定看看這個很有趣,下面是我得到的時間安排:
Swift 4.0.2 : 0.83s (0.74s with `-Ounchecked`)
C++ (Apple LLVM 8.0.0): 0.74s
迅速
// Swift 4.0 code
import Foundation
func doTest() -> Void {
let arraySize = 10000000
var randomNumbers = [UInt32]()
for _ in 0..<arraySize {
randomNumbers.append(arc4random_uniform(UInt32(arraySize)))
}
let start = Date()
randomNumbers.sort()
let end = Date()
print(randomNumbers[0])
print("Elapsed time: \(end.timeIntervalSince(start))")
}
doTest()
結果:
斯威夫特1.1
xcrun swiftc --version
Swift version 1.1 (swift-600.0.54.20)
Target: x86_64-apple-darwin14.0.0
xcrun swiftc -O SwiftSort.swift
./SwiftSort
Elapsed time: 1.02204304933548
斯威夫特1.2
xcrun swiftc --version
Apple Swift version 1.2 (swiftlang-602.0.49.6 clang-602.0.49)
Target: x86_64-apple-darwin14.3.0
xcrun -sdk macosx swiftc -O SwiftSort.swift
./SwiftSort
Elapsed time: 0.738763988018036
雨燕2.0
xcrun swiftc --version
Apple Swift version 2.0 (swiftlang-700.0.59 clang-700.0.72)
Target: x86_64-apple-darwin15.0.0
xcrun -sdk macosx swiftc -O SwiftSort.swift
./SwiftSort
Elapsed time: 0.767306983470917
如果我用編譯,性能似乎相同-Ounchecked。
斯威夫特3.0
xcrun swiftc --version
Apple Swift version 3.0 (swiftlang-800.0.46.2 clang-800.0.38)
Target: x86_64-apple-macosx10.9
xcrun -sdk macosx swiftc -O SwiftSort.swift
./SwiftSort
Elapsed time: 0.939633965492249
xcrun -sdk macosx swiftc -Ounchecked SwiftSort.swift
./SwiftSort
Elapsed time: 0.866258025169373
似乎是一個性能回歸從雨燕2.0至3.0雨燕,而且我也看到之間的差異-O,并-Ounchecked首次。
迅捷4.0
xcrun swiftc --version
Apple Swift version 4.0.2 (swiftlang-900.0.69.2 clang-900.0.38)
Target: x86_64-apple-macosx10.9
xcrun -sdk macosx swiftc -O SwiftSort.swift
./SwiftSort
Elapsed time: 0.834299981594086
xcrun -sdk macosx swiftc -Ounchecked SwiftSort.swift
./SwiftSort
Elapsed time: 0.742045998573303
Swift 4再次提高了性能,同時保持-O和之間的差距-Ounchecked。-O -whole-module-optimization似乎沒有什么不同。
C ++
#include <chrono>
#include <iostream>
#include <vector>
#include <cstdint>
#include <stdlib.h>
using namespace std;
using namespace std::chrono;
int main(int argc, const char * argv[]) {
const auto arraySize = 10000000;
vector<uint32_t> randomNumbers;
for (int i = 0; i < arraySize; ++i) {
randomNumbers.emplace_back(arc4random_uniform(arraySize));
}
const auto start = high_resolution_clock::now();
sort(begin(randomNumbers), end(randomNumbers));
const auto end = high_resolution_clock::now();
cout << randomNumbers[0] << "\n";
cout << "Elapsed time: " << duration_cast<duration<double>>(end - start).count() << "\n";
return 0;
}
結果:
蘋果C6.0
clang++ --version
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix
clang++ -O3 -std=c++11 CppSort.cpp -o CppSort
./CppSort
Elapsed time: 0.688969
蘋果C 6.1.0
clang++ --version
Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix
clang++ -O3 -std=c++11 CppSort.cpp -o CppSort
./CppSort
Elapsed time: 0.670652
蘋果Clang 7.0.0
clang++ --version
Apple LLVM version 7.0.0 (clang-700.0.72)
Target: x86_64-apple-darwin15.0.0
Thread model: posix
clang++ -O3 -std=c++11 CppSort.cpp -o CppSort
./CppSort
Elapsed time: 0.690152
蘋果鐺8.0.0
clang++ --version
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
clang++ -O3 -std=c++11 CppSort.cpp -o CppSort
./CppSort
Elapsed time: 0.68253
蘋果Clang 9.0.0
clang++ --version
Apple LLVM version 9.0.0 (clang-900.0.38)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
clang++ -O3 -std=c++11 CppSort.cpp -o CppSort
./CppSort
Elapsed time: 0.736784
判決
在撰寫本文時,Swift的排序速度很快,但-O與使用上述編譯器和庫進行編譯時,C ++的排序還不及C ++的排序。使用-Ounchecked,它似乎與Swift 4.0.2和Apple LLVM 9.0.0中的C ++一樣快。
- 3 回答
- 0 關注
- 777 瀏覽
添加回答
舉報