この記事はWeChatの公開アカウント「Backend Research Institute」から転載したもので、著者はDabaiskiです。この記事を転載する場合は、バックエンド研究所の公式アカウントまでご連絡ください。 序文今日は、STL でのソート アルゴリズムの基礎となる実装とコーディング手法を見てみましょう。 ご存知のとおり、STL はデータ構造とアルゴリズムの一般化をサポートするためにテンプレートに依存しています。一般化は C++ ユーザーにとってすでに驚きですが、STL 開発者の強力なラインナップを見ると、STL がもたらす驚きは一般化にとどまらないことがわかります。強力なパフォーマンスと効率性により、STL はさらに素晴らしいものになっています。 STL の究極のパフォーマンスの背後には、熟練プログラマーの優れたプログラミング スキルと完璧さを追求する職人精神がまさに体現されています。 私の能力の限界により、先人たちの肩を追って STL のソート アルゴリズムの背後に何が隠されているかを調べることしかできません。まるで「Into Science」のワンシーンのようですね。では、ソート アルゴリズムの旅を始めましょう。 内省的哲学ソートアルゴリズムの実装を理解する前に、イントロスペクティブソートという概念を見てみましょう。正直に言うと、私の中国語レベルは本当に平均的で、ソートアルゴリズムで使用されるこの用語は明確ではないといつも感じているので、勉強しましょう。 イントロスペクティブソートは英語で Introspective Sort と呼ばれます。introspective という言葉は内省的な意味です。まだよくわかりません。検索を続け、この用語の Baidu Encyclopedia の説明を見てみます。 内省は心理学における基本的な研究方法の一つです。内省は自己観察とも呼ばれます。それは内部で発生し、私たち自身も認識している主観的な現象です。それは、自分自身の主観的な経験とその変化の観察であるとも言えます。 内省はまさにその主観性ゆえに、心理学の分野では古代から長年の論争の的となってきました。また、内省は自己反省とも言え、儒教が重視する自己思考でもあります。この観点から、Java イントロスペクション メカニズムや Cocoa イントロスペクション メカニズムなどのコンピュータ分野に応用できます。 わあ、内省は心理学用語だということがわかりました。これで少し理解できました。内省とは、外の世界に希望を託すのではなく、自分自身の経験と能力に基づいて、自己を振り返り、自分で考え、変化を観察し、自分の主観的な経験に基づいて調整することを意味します。 簡単に言えば、イントロスペクション アルゴリズムはデータ セットを選り好みせず、ソートが時間内に保証されるように、各データ セットに対応する処理方法を提供しようとします。 これを書いていると、「天剣龍驤」で張無忌が光明山で六大宗派と戦う場面が頭に浮かびます。敵がどんなに強くても弱くても、私は自分のやり方で対処します。 彼は強いので強い、そよ風が丘を越えて吹き渡る。 彼が望むままにさせておけば、明るい月が川面を照らします。 彼は残酷で邪悪だが、私には十分なエネルギーがある。 --- 達磨の『九陽経』 哲学、その通りです。分類の視点に切り替えて、内省のプロセスを見てみましょう。 私が理解する内省的ソート アルゴリズムは、外部データの品質や量に依存せず、それぞれの極端なシナリオに対する独自の対応に基づいて対応する判断と決定の調整を行い、さまざまなデータ セットに適応して優れたパフォーマンスを発揮するアルゴリズムです。 内省的ソート諺にあるように、英雄はナイフ、銃、剣、戟、斧、手斧、フック、フォークなど、多くの武器を使用します。これは、無敵の武器はなく、特定のシナリオでのみ明らかな利点があることを示しています。これは、ソフトウェア エンジニアリングに特効薬がないのと同じです。 ソートアルゴリズムに戻ると、バブルソート、選択ソート、挿入ソート、クイックソート、ヒープソート、バケットソートなど、ソートアルゴリズムは多数あります。 古いソートアルゴリズムの多くは O(n^2) ですが、優れたアルゴリズムは O(nlogn) に到達できます。ただし、nlogn であるクイックソートやヒープソートにも、それぞれ長所と短所があります。挿入ソートは、データがほぼ順序付けられている場合に O(n) のパフォーマンスを達成できます。場合によっては、競合比較ではなく、統合と革新を行う必要があります。 イントロスペクティブソートは、1997 年に David Musser によって設計されたソートアルゴリズムです。このソートアルゴリズムはクイックソートから始まり、再帰の深さが一定の深さを超えるとヒープソートに切り替わります (深さはソートされた要素の数の対数です)。David Musser は STL 分野ではよく知られた人物です。 文脈を考慮せずに、盲目的にどちらが良いか悪いかを比較するのは意味がありません。イントロスペクティブソートは、それらすべてを集大成したものです。ソートアルゴリズムが総合的に優れたパフォーマンスを実現できるように、イントロスペクティブソートアルゴリズムは、クイックソート、ヒープソート、挿入ソートを組み合わせ、現在のデータセットの特性に基づいてどのソートアルゴリズムを使用するかを選択し、各アルゴリズムが独自の長所を発揮できるようにします。このアイデアは確かに非常に刺激的です。 デプロイメントの内省的なソート前述のように、イントロスペクティブ ソートは主にクイック ソート、ヒープ ソート、挿入ソートを組み合わせたものです。では、これら 3 つのソートはどのように配置されているのでしょうか。 自分と敵を知ることで、あらゆる戦いで勝利が保証されます。まずは、3 つの分類の長所と短所を見てみましょう。 クイックソート 大量のデータの場合、順序付きか繰り返しかに関係なく、最適化されたアルゴリズムはほとんどの場合 O(nlogn) に到達できます。ヒープソートも O(nlogn) ですが、クイックソートの方がいくつかの理由で高速です。再帰が深すぎてセグメンテーションが著しく不均一な場合、O(n^2) の複雑さに退化し、パフォーマンスが低下します。これがクイックソートの欠点です。 ヒープソート ヒープソートはクイックソートの強力な競合相手です。その最大の特徴は、O(nlogn) に到達でき、その複雑性が非常に安定していることです。クイックソートのように O(n^2) に低下することはありません。ただし、ヒープソートプロセスには多くのヒープ調整が含まれ、要素の比較はジャンプ方式で行われるため、キャッシュの局所性特性が十分に活用されません。その他の理由と同様に、ヒープソートはクイックソートよりも少し遅くなりますが、ビッグ O の複雑性は依然として同じレベルです。 挿入ソート 挿入ソートの特徴の 1 つは、トランプに似ていることです。手札のカードをソートする場合、カードがすでに整列していれば、調整はほとんど必要ありません。したがって、データ量が多くなく、ほぼ整列している場合は、挿入ソートの複雑さは O(n) にまで削減できるため、適用する価値があります。 利点と欠点は大体明らかなので、イントロスペクティブ ソートが実際にこれら 3 つのソート アルゴリズムをどのようにスケジュールするかを推測できます。
これを書き終えて、著者は次のような場面を思いつきました。 2005年春節祝賀会のスケッチ「装飾」で、黄紅と龔翰林が演じた。装飾役の黄紅は、大小2本のハンマーを持っていた。大ハンマーは80ポンド、小ハンマーは40ポンドで、大小のハンマーを切り替えることができた。 実際、ソートアルゴリズムを内省的ソートに切り替えるのと同じです。つまり、テクノロジーは生命から生まれ、生命よりも高いのです。以下は、みんなで一緒に体験できる画像です。 イントロスペクションとイントロスペクティブソートについて長々と説明してきました。皆さんはもう理解していると思いますので、実装の詳細を詳しく見ていきましょう。これがこの記事の焦点です。一緒に分析を続けていきましょう! ソートアルゴリズムの実装の詳細この記事で紹介したソートアルゴリズムは、SGI STLバージョンに基づいており、主に侯潔先生の著書「STLソースコード分析」に基づいています。そのため、関数のないバージョンが使用されています。専門家の傑作を一緒に鑑賞しましょう!写真は、著者がずっと前に購入したが、常に箱の底に保管していたSTLマジックブックです。 ソート機能の応用シナリオSGI STL のソートのパラメータは 2 つのランダム アクセス イテレータ RandomAccessIterator であり、ソート テンプレートもこの種のイテレータに基づいています。したがって、コンテナーがランダム アクセス イテレータでない場合は、一般的なソート関数を使用できない可能性があります。
要約すると、ソート アルゴリズムは、ベクター コンテナーとデキュー コンテナーの両方に適用できることがわかります。 並べ替え 概要先ほどイントロスペクティブ ソートを紹介しましたので、sort が introsort をどのように使用するかをステップごとに見ていきましょう。前回のエントリ コードは次のとおりです。
コードから、sort はソートするシーケンスの開始と終了として 2 つのランダム アクセス イテレータ (first と last) を使用し、さらに 2 つの関数 __introsort_loop と __final_insertion_sort を呼び出すことがわかります。文字通り、前者はイントロスペクティブ ソート ループであり、後者は挿入ソートです。 __introsort_loop の 3 番目のパラメータは __lg(last - first)*2 であることに注意してください。経験に基づいて、これが再帰の深さの限界であると推測します。コード実装を見てみましょう。
このコードは、n=last-first、つまり 2^k<=n の最大の整数 k 値を意味します。 したがって、全体として、last-first=20、k=4 と仮定すると、最大セグメンテーション深度 depth_max=4*2=8 となり、first と last に基づいて再帰の最大深度を決定できます。 クイック ソートとヒープ ソートの調整 __introsort_loop 関数は、主にクイック ソートとヒープ ソートをカプセル化します。この関数の実装の詳細を見てみましょう。
めまいや混乱を感じないでください。少し分析すれば必ず理解できます。
クイックソートの実装の比較前述のように、sort でのクイック ソートの記述は、これまで見てきたものとは多少異なります。「STL ソース コード分析」でクイック ソートの左シーケンスの処理を見た後、Hou Jie 先生は次のように書いています。「記述が読みにくく、効率も良くありません。」これを見て、私はさらに混乱しましたが、分析してみましょう。 写真: STLソースコード解析におけるこの記述方法についてのHou Jie先生のコメント 一般的な書き方:
SGI STL で記述する方法:
インターネット上の大物による記事によると、SGI STL のクイック ソートの記述方法では、while ループを使用することで再帰呼び出しが半分に削減されるとのことですが、これは典型的な末尾再帰の最適化のアイデアです。 ここでは比較のためのテスト コードをまだ書いていません。まずピットを取り上げて、後で比較テストを書いてからコメントします。ただし、sgi のこの書き方を見ることはできます。 ヒープソートの詳細
挿入ソートが作用する__introsort_loop が __stl_threshold しきい値に達すると、データセットはほぼ順序付けられたとみなすことができます。このとき、挿入ソートによってソート速度をさらに向上させることができ、再帰によるシステム消費も回避できます。__final_insertion_sort の具体的な実装を見てみましょう。
__final_insertion_sort の実装の詳細を分析してみましょう。
__insertion_sortの実装
挿入された関数には、__unguarded_xxx 形式の関数も表示されます。unguarded という単語は、保護されていない、保護されていないという意味です。Hou Jie 氏は、この形式の関数は、境界チェック条件なしで特定の条件下で正しく実行できる関数であると述べています。 copy_backward も全体的な移動の最適化であり、1 つずつの調整と移動を回避し、効率的な実装のために基礎となる memmove が呼び出されます。 __unguarded_insertion_sort の実装
挿入ソートのこの 2 つの機能の実装と目的は非常に詳細なので、後で挿入ソートを書くときに個別に勉強したいと思います。したがって、この記事では今のところそれについては触れません。興味のある読者はまず関連資料を読んでください。後で一緒に反論します。 要約するこの記事では、主にイントロスペクティブ ソートの考え方と基本的な実装について説明し、これを出発点として SGI STL でのソート アルゴリズムの実装を解釈します。 stl の作者たちは、究極のパフォーマンスを追求するために多くのテクニックを使用しました。この記事では、主に私があまり知識がなく、誤解を恐れているため、これについて詳しく説明しません。賢明な読者は、マスターたちの最高のスキルを分析し、探求してみてください。 |
>>: 2021年世界人工知能会議が開幕。董明珠、馬化騰、李延紅、周紅一などの大物たちは何を語ったのか?
機械学習におけるデータバイアスとは、データセットの一部の要素が他の要素よりも重み付けされ、または高く...
[[403918]]近年、経済の継続的な発展に伴い、わが国では中間所得層の総数が増加しています。現在...
3月15日、毎年恒例のCCTV Finance 3.15 Galaが開催されています。序文から判断す...
[[196940]]多くの学生は、フードデリバリーはオンラインで注文し、オフラインで配達するビジネス...
世界各国の政府は新型コロナウイルス感染症の流行に対抗するためさまざまな対策を講じているが、世界的な流...
[[225622]]画像出典: Photo Network潔面は4月10日、教育部が最近「高等教育機...
SF作家の劉慈欣はかつて、自身の小説の中でこのような天気予報を描写した。小説の主人公は気象大学を卒...
この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...
この記事は公開アカウント「Reading Core Technique」(ID: AI_Discov...
[[437396]]コネチカット州スタンフォード — 新しいレポートによると、人工知能 (AI) を...
ニンジン畑問題を解決するための C# アルゴリズムは何ですか?まずトピックを見てみましょう:仕事へ向...
最近、OpenAI の主任科学者 Ilya Sutskever 氏が、計算理論の研究に重点を置く S...