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

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

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

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

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

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

ライアン・フェルトンがジャロプニックを去る。アメリカの詐欺と嘘つきは安堵のため息をつく。スタッフが再び昼食時に肉を注文する

ライアン・フェルトンがジャロプニックを去る。アメリカの詐欺と嘘つきは安堵のため息をつく。スタッフが再び昼食時に肉を注文する

「あなたは知っているべきです」とライアン・フェルトンは電話にひそかに言いました、「私は本当にできないこと。

今日だけMovadoウォッチが50%オフで、手首にちょっとした贅沢を加えましょう

今日だけMovadoウォッチが50%オフで、手首にちょっとした贅沢を加えましょう

ノードストロームラックのMovadoイベントMovadoは、クラシックで象徴的な時計ブランドですが、価格が1,000ドルを超えるため、ほとんどの人にとって信じられないほど手に負えないと感じる可能性があります。しかし、ノードストロームラックのMovadoイベントを使用すると、小売価格の半分でゴージャスな時計を獲得できます。いくつかのスタイルは400ドル未満で提供されます。

L7は18年ぶりのショーをプレイしました

L7は18年ぶりのショーをプレイしました

これは素晴らしいことです。L7のオリジナルラインナップは18年ぶりに再会し、LAのエコーで完売したショーを演奏しました。

「またの名をグレイス」は、見られているという不穏な感覚を体現しています。

「またの名をグレイス」は、見られているという不穏な感覚を体現しています。

「またの名をグレイス」ジョーダン博士は、19世紀半ばのカナダの性別の役割と階級の違いが、グレイスの心を解き放とうとし続けています。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

エッジ機能とは?!?

エッジ機能とは?!?

エッジ機能…それはセクシーに聞こえます、あなたのおばあちゃんはそれが何であるかを知らないでしょう、そしてあなたはおそらくまだどちらも知らないでしょう。それは大丈夫です、うまくいけば、私はより簡単な方法でエッジを理解するためのあなたの旅であなたを助けるためにここにいます。

また、より顧客重視を「試み」ていますか?

また、より顧客重視を「試み」ていますか?

顧客が好きなものから、顧客が好き/嫌いなものについて利害関係者の内臓が言うものに焦点が移る製品機能の議論を経験したことがありますか?チームの全員がお互いに何をすべきかを尋ねていて、誰もその製品に興味を持っていないように見える時期を経験したことがありますか?フィードバックループフィードバック—否定的な意味合いがありますよね?実際には、フィードバックは環境から私たちの行動への反応であり、私たちに利益をもたらすためにそれを使用するには、この反応を分析する必要があります。通常、これには従いません。

あなたがアメリカを怖がっているなら、あなたはまだ十分に怖がっていません

あなたがアメリカを怖がっているなら、あなたはまだ十分に怖がっていません

神学者とファシストは全体主義社会を望んでいます—そして彼らは世界中で1つの衝撃波を反響させようとしています。友人や人々でいっぱいの古いヨーロッパの古い街にある私の小さなカフェで、「彼らは本当にそれをしましたか?」「彼らはクレイジーですか?」「これからどうなるの?」"我が神よ!" 角を曲がったところにある公園で、犬たちは幸せな夏の輪の中で回転します。「信じられない!」「アメリカ人にできることはありますか?」"今、何が起きた?" 今、何が起きた?それがみんなの頭の中にある質問です。

私の技術の旅

速いお金があなたが望むものであるか、ストレスのない生活があなたが切望するものであるならば、私はあなたに技術があなたのものではないことを断固として言いたいです。私を信じて。

Language