Swift Betaのパフォーマンス:配列の並べ替え

941
Jukka Suomela 2014-06-08 13:53.

Swift Betaでアルゴリズムを実装していたところ、パフォーマンスが非常に悪いことに気づきました。深く掘り下げた後、ボトルネックの1つが配列の並べ替えと同じくらい単純なものであることに気付きました。関連する部分はここにあります:

let n = 1000000
var x =  [Int](repeating: 0, count: n)
for i in 0..<n {
    x[i] = random()
}
// start clock here
let y = sort(x)
// stop clock here

C ++では、同様の操作が私のコンピューターで0.06秒かかります。

Pythonでは、0.6秒かかります(トリックはありません。整数のリストに対してy = sorted(x)だけです)。

Swiftでは、次のコマンドでコンパイルすると6秒かかります。

xcrun swift -O3 -sdk `xcrun --show-sdk-path --sdk macosx`

そして、次のコマンドでコンパイルすると、88秒もかかります。

xcrun swift -O0 -sdk `xcrun --show-sdk-path --sdk macosx`

「リリース」ビルドと「デバッグ」ビルドを使用したXcodeのタイミングは似ています。

ここで何が問題になっていますか?C ++と比較してパフォーマンスがいくらか低下することは理解できましたが、純粋なPythonと比較して10倍の速度低下は理解できませんでした。


編集:天気は、に変更-O3すると-Ofast、このコードがC ++バージョンとほぼ同じ速度で実行されることに気づきました。ただし、-Ofast言語のセマンティクスは大幅に変更されます。私のテストでは、整数オーバーフローと配列インデックスオーバーフローのチェックが無効になりました。たとえば-Ofast、次の場合、Swiftコードはクラッシュすることなくサイレントに実行されます(そしてゴミを出力します)。

let n = 10000000
print(n*n*n*n*n)
let x =  [Int](repeating: 10, count: n)
print(x[n])

だから-Ofast私たちが望むものではありません。Swiftの要点は、セーフティネットが設置されていることです。もちろん、セーフティネットはパフォーマンスにいくらかの影響を及ぼしますが、プログラムを100倍遅くするべきではありません。Javaはすでに配列の境界をチェックしており、通常、速度低下は2倍未満であることを忘れないでください。ClangとGCC-ftrapvでは、(符号付き)整数オーバーフローをチェックする必要があり、それほど遅くはありません。

したがって、質問:セーフティネットを失うことなくSwiftで妥当なパフォーマンスを得るにはどうすればよいですか?


編集2:の線に沿った非常に単純なループで、さらにベンチマークを行いました

for i in 0..<n {
    x[i] = x[i] ^ 12345678
}

(ここでは、アセンブリコードで関連するループをより簡単に見つけることができるように、xor操作があります。関連するチェックを必要としないという意味で、見つけやすく、「無害」な操作を選択しようとしました。整数オーバーフローに。)

繰り返しますが、-O3との間でパフォーマンスに大きな違いがありました-Ofast。だから私はアセンブリコードを見ました:

  • -Ofast私は私が期待するものをほぼ得る。関連する部分は、5つの機械語命令を含むループです。

  • -O3私は私の想像を超えた何かを手に入れました。内側のループは88行のアセンブリコードにまたがっています。すべてを理解しようとはしませんでしたが、最も疑わしい部分は、「callq_swift_retain」の13回の呼び出しと「callq_swift_release」の13回の呼び出しです。つまり、内側のループで26個のサブルーチンが呼び出されます


編集3:コメントの中で、Ferruccioは、組み込み関数(ソートなど)に依存しないという意味で公正なベンチマークを求めました。次のプログラムはかなり良い例だと思います。

let n = 10000
var x = [Int](repeating: 1, count: n)
for i in 0..<n {
    for j in 0..<n {
        x[i] = x[j]
    }
}

算術演算がないため、整数オーバーフローについて心配する必要はありません。私たちが行う唯一のことは、たくさんの配列参照です。結果は次のとおりです。Swift-O3は、-Ofastと比較して約500倍の損失があります。

  • C ++ -O3:0.05秒
  • C ++ -O0:0.4秒
  • Java:0.2秒
  • PyPyを使用したPython:0.5秒
  • Python:12秒
  • Swift -Ofast:0.05秒
  • Swift -O3:23秒
  • Swift -O0:443秒

(コンパイラが無意味なループを完全に最適化する可能性がある場合は、たとえばx[i] ^= x[j]に変更して、出力するprintステートメントを追加できますx[0]。これは何も変更しません。タイミングは非常に似ています。)

そして、はい、ここでのPython実装は、intのリストとネストされたforループを備えた愚かな純粋なPython実装でした。最適化されていないSwiftよりもはるかに遅いはずです。Swiftと配列のインデックス作成で何かが深刻に壊れているようです。


編集4:これらの問題(およびその他のパフォーマンスの問題)は、Xcode6ベータ5で修正されたようです。

並べ替えのタイミングは次のとおりです。

  • clang ++ -O3:0.06秒
  • swiftc -Ofast:0.1秒
  • swiftc -O:0.1秒
  • swiftc:4秒

ネストされたループの場合:

  • clang ++ -O3:0.06秒
  • swiftc -Ofast:0.3秒
  • swiftc -O:0.4秒
  • swiftc:540秒

安全でない-Ofast(別名-Ounchecked)を使用する理由はもうないようです。プレーン-Oは同様に良いコードを生成します。

9 answers

464
Joseph Mark 2014-06-08 15:36.

tl; dr Swift 1.0は、デフォルトのリリース最適化レベル[-O]を使用して、このベンチマークでCと同じくらい高速になりました。


SwiftBetaのインプレースクイックソートは次のとおりです。

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

n = 10_000に対するSwiftの組み込みsort()は次のとおりです。

Swift_builtin:    0.77865783

ここで[-O]のためにN = 10_000

Swift:            0.045478346
C:                0.000784666
Swift_builtin:    0.032513488

ご覧のとおり、Swiftのパフォーマンスは20倍向上しました。

あたりとしてSwift Betaのパフォーマンス:配列の並べ替え、設定[-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] for n = 1_000_000の場合です:

Swift:            142.659763258
C:                0.162065333
Swift_sort:       114.095478272

したがって、最適化されていないSwiftは、開発のこの段階では、このベンチマークのCよりもほぼ1000倍遅くなりました。一方、両方のコンパイラを[-Ofast]に設定すると、Swiftは実際にはCよりわずかに優れていないとしても少なくとも同様に機能しました。

[-Ofast]は言語のセマンティクスを変更し、潜在的に安全でなくなることが指摘されています。これは、AppleがXcode5.0リリースノートで述べていることです。

LLVMで利用可能な新しい最適化レベル-Ofastは、積極的な最適化を可能にします。-Ofastは、ほとんどのコードで安全な、主に浮動小数点演算に関するいくつかの保守的な制限を緩和します。それはコンパイラから重要な高性能の勝利をもたらすことができます。

彼らはほとんどそれを支持しています。それが賢明かどうかは言えませんが、高精度の浮動小数点演算を行っておらず、整数または整数がないと確信している場合は、リリースで[-Ofast]を使用するのが十分合理的であると言えます。プログラムで配列オーバーフローが発生する可能性があります。高性能オーバーフローチェック/正確な演算が必要な場合は、今のところ別の言語を選択してください。

ベータ3アップデート:

n = 10_000[-O]

Swift:            0.019697268
C:                0.000718064
Swift_sort:       0.002094721

Swiftは一般的に少し高速で、Swiftの組み込みの並べ替えが大幅に変更されたように見えます。

最終更新:

[-オノン]

Swift:   0.678056695
C:       0.000973914

[-O]

Swift:   0.001158492
C:       0.001192406

[-未チェック]

Swift:   0.000827764
C:       0.001078914
111
filcab 2014-06-09 20:30.

TL; DR:はい、現時点では、Swift言語の実装は遅いだけです。高速な数値(およびおそらく他のタイプのコード)コードが必要な場合は、別のコードを使用してください。将来的には、選択を再評価する必要があります。ただし、より高いレベルで記述されたほとんどのアプリケーションコードには十分かもしれません。

私がSILとLLVMIRで見ていることから、Clang(Objective-Cの場合)で実装される可能性のある保持とリリースを削除するための一連の最適化が必要なようですが、まだ移植されていません。この質問の最後のテストケースでプロファイラーを実行すると、次のような「きれいな」結果が得られるため、これが私が行っている理論です(今のところ、Clangがそれについて何かを行うことを確認する必要があります)。

他の多くの人が言ったように、-Ofast完全に安全ではなく、言語のセマンティクスを変更します。私にとっては、「それを使用する場合は、別の言語を使用する」段階です。変更された場合は、後でその選択を再評価します。

-O3私たちにたくさんのことを聞いて、正直なところ、この例ではそこにあるべきではないように見えるswift_retainswift_release呼びます。オプティマイザーは、アレイに関するほとんどの情報を知っており、(少なくとも)それを強く参照していることを知っているので、(ほとんどの)AFAICTを排除する必要があります。

オブジェクトを解放する可能性のある関数を呼び出さない場合でも、それ以上の保持を放出するべきではありません。配列コンストラクターが要求されたものよりも小さい配列を返すことはできないと思います。つまり、発行された多くのチェックは役に立たないということです。また、整数が10kを超えることはないこともわかっているため、オーバーフローチェック最適化できます(-Ofast奇妙さのためではなく、言語のセマンティクスのためです(varを変更したり、それにアクセスしたりすることはできず、合計で10kになります)。タイプに対して安全ですInt)。

ただし、sort()外部関数であり、期待する引数を取得する必要があるに渡されるため、コンパイラは配列または配列要素のボックス化を解除できない場合があります。これにより、Int値を間接的に使用する必要があり、少し遅くなります。これは、sort()汎用関数(マルチメソッド方式ではない)がコンパイラーで使用可能であり、インライン化されている場合に変更される可能性があります。

これは非常に新しい(公的)言語であり、そしてそれは私が仮定何を通過しているのフィードバックを求めスウィフト言語に関与(多額の)人々があるので、多くの変更であり、彼らはすべての言語が完成していないと言う意志変化する。

使用したコード:

import Cocoa

let swift_start = NSDate.timeIntervalSinceReferenceDate();
let n: Int = 10000
let x = Int[](count: n, repeatedValue: 1)
for i in 0..n {
    for j in 0..n {
        let tmp: Int = x[j]
        x[i] = tmp
    }
}
let y: Int[] = sort(x)
let swift_stop = NSDate.timeIntervalSinceReferenceDate();

println("\(swift_stop - swift_start)s")

PS:私はObjective-Cの専門家でも、Cocoa、Objective-C、またはSwiftランタイムのすべての機能の専門家でもありません。私はまた、私が書いていなかったいくつかのことを想定しているかもしれません。

55
Learn OpenGL ES 2014-10-27 11:47.

私は楽しみのためにこれを見てみることにしました、そしてここに私が得るタイミングがあります:

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

Swift 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です。

Swift 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初めてを。

Swift 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;
}

結果:

Apple Clang 6.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

Apple Clang 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

Apple 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

Apple Clang 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

Apple 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 ++のソートほど高速ではありません。を使用すると-Ounchecked、Swift4.0.2およびAppleLLVM9.0.0のC ++と同じくらい高速になります。

34
David Skrundz 2014-06-08 14:29.

差出人The Swift Programming Language

並べ替え関数Swiftの標準ライブラリには、指定した並べ替えクロージャの出力に基づいて、既知の型の値の配列を並べ替えるsortという関数が用意されています。並べ替えプロセスが完了すると、並べ替え関数は、古い配列と同じタイプとサイズの新しい配列を返し、その要素は正しい並べ替え順序になります。

このsort関数には2つの宣言があります。

比較クロージャを指定できるデフォルトの宣言:

func sort<T>(array: T[], pred: (T, T) -> Bool) -> T[]

そして、単一のパラメーター(配列)のみを取り、「より小さいコンパレーターを使用するようにハードコードされている」2番目の宣言。

func sort<T : Comparable>(array: T[]) -> T[]

Example:
sort( _arrayToSort_ ) { $0 > $1 }

関数をもう少し詳しく監視できるように、クロージャーを追加した遊び場でコードの修正バージョンをテストしたところ、nを1000に設定すると、クロージャーが約11,000回呼び出されていたことがわかりました。

let n = 1000
let x = Int[](count: n, repeatedValue: 0)
for i in 0..n {
    x[i] = random()
}
let y = sort(x) { $0 > $1 }

これは効率的な関数ではありません。より適切な並べ替え関数の実装を使用することをお勧めします。

編集:

クイックソートのウィキペディアのページを見て、Swiftの実装を作成しました。これが私が(遊び場で)使った完全なプログラムです

import Foundation

func quickSort(inout array: Int[], begin: Int, end: Int) {
    if (begin < end) {
        let p = partition(&array, begin, end)
        quickSort(&array, begin, p - 1)
        quickSort(&array, p + 1, end)
    }
}

func partition(inout array: Int[], left: Int, right: Int) -> Int {
    let numElements = right - left + 1
    let pivotIndex = left + numElements / 2
    let pivotValue = array[pivotIndex]
    swap(&array[pivotIndex], &array[right])
    var storeIndex = left
    for i in left..right {
        let a = 1 // <- Used to see how many comparisons are made
        if array[i] <= pivotValue {
            swap(&array[i], &array[storeIndex])
            storeIndex++
        }
    }
    swap(&array[storeIndex], &array[right]) // Move pivot to its final place
    return storeIndex
}

let n = 1000
var x = Int[](count: n, repeatedValue: 0)
for i in 0..n {
    x[i] = Int(arc4random())
}

quickSort(&x, 0, x.count - 1) // <- Does the sorting

for i in 0..n {
    x[i] // <- Used by the playground to display the results
}

これをn = 1000で使用すると、

  1. quickSort()は約650回呼び出されました。
  2. 約6000回のスワップが行われました。
  3. 約10,000の比較があります

組み込みのソート方法はクイックソートである(またはそれに近い)ようで、本当に遅いです...

18
Antoine 2015-06-12 06:56.

Xcode 7以降、をオンにすることができますFast, Whole Module Optimization。これにより、パフォーマンスがすぐに向上します。

12
Duncan C 2016-02-26 15:31.

Swiftアレイのパフォーマンスの再検討:

SwiftとC / Objective-Cを比較する独自のベンチマークを作成しました。私のベンチマークは素数を計算します。以前の素数の配列を使用して、新しい各候補の素因数を検索するため、非常に高速です。ただし、大量の配列の読み取りを行い、配列への書き込みは少なくなります。

私はもともとSwift1.2に対してこのベンチマークを行いました。プロジェクトを更新して、Swift2.0に対して実行することにしました。

このプロジェクトでは、通常のSwift配列を使用するか、配列セマンティクスを使用してSwiftの安全でないメモリバッファーを使用するかを選択できます。

C / Objective-Cの場合、NSArraysまたはCmallocされた配列のいずれかを使用することを選択できます。

テスト結果は、最速の最小コード最適化([-0s])または最速のアグレッシブ([-0fast])最適化と非常に似ているようです。

Swift 2.0のパフォーマンスは、コードの最適化をオフにしてもひどいものですが、C / Objective-Cのパフォーマンスはやや遅くなります。

結論として、Cのmallocされた配列ベースの計算は、適度なマージンで最速です。

安全でないバッファを使用したSwiftは、最速で最小のコード最適化を使用した場合、Cmallocの配列よりも約1.19倍から1.20倍長くかかります。高速で積極的な最適化を行うと、違いはわずかに少なくなります(SwiftはCより1.18倍から1.16倍長くかかります。

通常のSwiftアレイを使用する場合、Cとの違いはわずかに大きくなります。(Swiftは約1.22から1.23長くかかります。)

通常のSwiftアレイはDRAMATICALLY、Swift 1.2 / Xcode 6よりも高速です。パフォーマンスはSwiftの安全でないバッファーベースのアレイに非常に近いため、安全でないメモリバッファーを使用しても、問題を解決する価値はありません。これは大きな問題です。

ところで、Objective-CNSArrayのパフォーマンスは悪臭を放ちます。両方の言語でネイティブコンテナオブジェクトを使用する場合、Swiftは劇的に高速です。

SwiftPerformanceBenchmarkのgithubで私のプロジェクトをチェックできます

統計の収集を非常に簡単にするシンプルなUIを備えています。

Swiftのソートは現在Cよりもわずかに速いように見えますが、この素数アルゴリズムはSwiftの方がまだ速いのは興味深いことです。

8
Joseph Lord 2016-04-14 00:58.

他の人が言及しているが十分に呼び出されていない主な問題は-O3、Swiftではまったく何もしない(そして決して持っていない)ので、それでコンパイルすると事実上最適化されない(-Onone)。

オプション名は時間の経過とともに変更されたため、他のいくつかの回答にはビルドオプションの廃止されたフラグがあります。現在の正しいオプション(Swift 2.2)は次のとおりです。

-Onone // Debug - slow
-O     // Optimised
-O -whole-module-optimization //Optimised across files

モジュール全体の最適化はコンパイルが遅くなりますが、モジュール内のファイル間、つまり各フレームワーク内および実際のアプリケーションコード内で最適化できますが、それらの間では最適化できません。パフォーマンスが重要な場合はこれを使用する必要があります)

安全性チェックを無効にしてさらに速度を上げることもできますが、すべてのアサーションと前提条件を無効にするだけでなく、正しいことに基づいて最適化します。アサーションにヒットした場合、これは未定義の動作に陥っていることを意味します。スピードブーストがあなたにとって価値があると判断した場合にのみ、細心の注意を払って使用してください(テストによって)。一部のコードにとって価値があると思われる場合は、そのコードを別のフレームワークに分割し、そのモジュールの安全性チェックのみを無効にすることをお勧めします。

7
Abo3atef 2016-12-07 01:12.
func partition(inout list : [Int], low: Int, high : Int) -> Int {
    let pivot = list[high]
    var j = low
    var i = j - 1
    while j < high {
        if list[j] <= pivot{
            i += 1
            (list[i], list[j]) = (list[j], list[i])
        }
        j += 1
    }
    (list[i+1], list[high]) = (list[high], list[i+1])
    return i+1
}

func quikcSort(inout list : [Int] , low : Int , high : Int) {

    if low < high {
        let pIndex = partition(&list, low: low, high: high)
        quikcSort(&list, low: low, high: pIndex-1)
        quikcSort(&list, low: pIndex + 1, high: high)
    }
}

var list = [7,3,15,10,0,8,2,4]
quikcSort(&list, low: 0, high: list.count-1)

var list2 = [ 10, 0, 3, 9, 2, 14, 26, 27, 1, 5, 8, -1, 8 ]
quikcSort(&list2, low: 0, high: list2.count-1)

var list3 = [1,3,9,8,2,7,5]
quikcSort(&list3, low: 0, high: list3.count-1) 

これはクイックソートについての私のブログです-Githubサンプルクイックソート

リストのパーティショニングで、Lomutoのパーティショニングアルゴリズムを確認できます。Swiftで書かれています。

4
casillas 2018-12-15 17:25.

Swift 4.1では、新しい-Osize最適化モードが導入されています。

Swift 4.1では、コンパイラーは、コードサイズを削減するための専用の最適化を可能にする新しい最適化モードをサポートするようになりました。

Swiftコンパイラには強力な最適化が付属しています。-Oを使用してコンパイルする場合、コンパイラーは、最大のパフォーマンスで実行されるようにコードを変換しようとします。ただし、このランタイムパフォーマンスの向上には、コードサイズの増加とのトレードオフが伴う場合があります。新しい-Osize最適化モードでは、ユーザーは最大速度ではなく最小コードサイズでコンパイルすることを選択できます。

コマンドラインでサイズ最適化モードを有効にするには、-Oの代わりに-Osizeを使用します。

さらに読む:https//swift.org/blog/osize/

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする&nbsp;

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

パンデミックは終わったかもしれないが、Covid-19 は終わっていない

パンデミックは終わったかもしれないが、Covid-19 は終わっていない

2021 年 6 月 8 日にニューヨーク市で開催された covid-19 パンデミックで亡くなった人々の命を偲び、祝うために、ネーミング ザ ロスト メモリアルズが主催するイベントと行進の最中に、グリーンウッド墓地の正門から記念碑がぶら下がっています。週末、ジョー・バイデン大統領は、covid-19 パンデミックの終息を宣言しました。これは、過去 2 年以上にわたり、公の場でそうするための長い列の中で最新のものです。

デビル・イン・オハイオの予告編は、エミリー・デシャネルもオハイオにいることを明らかにしています

デビル・イン・オハイオの予告編は、エミリー・デシャネルもオハイオにいることを明らかにしています

オハイオ州のエミリー・デシャネル みんな早く来て、ボーンズが帰ってきた!まあ、ショーボーンズではなく、彼女を演じた俳優. エミリー・デシャネルに最後に会ってからしばらく経ちました.Emily Deschanel は、長期にわたるプロシージャルな Bones の Temperance “Bones” Brennan としてよく知られています。

ドナルド・トランプはFBIのマー・ア・ラーゴ襲撃映像をリリースする予定ですか?

ドナルド・トランプはFBIのマー・ア・ラーゴ襲撃映像をリリースする予定ですか?

どうやら、ドナルド・トランプに近い人々は、今月初めにFBIによって家宅捜索された彼のMar-a-Lago財産からの映像を公開するよう彼に勧めています. 前大統領はテープを公開するかどうかを確認していませんが、息子はフォックス・ニュースにそうなるだろうと語った.

Andor は、他の Star Wars ショーから大きな距離を置きます。

Andor は、他の Star Wars ショーから大きな距離を置きます。

アンドールの一場面。数十年前、ジョージ・ルーカスがスター・ウォーズのテレビ番組を制作するのを妨げた主な理由は、お金でした。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language