関数 - 構造体の配列をソートするためのメソッド。賞金10ドル - ページ 9 123456789 新しいコメント 削除済み 2020.06.18 16:10 #81 Dmitry Fedoseev:なぜ?そのためのトピックは別にあるのでしょうか? グッドアイディア )))) チキチキ...」というトピックを立ち上げるべき。" ))))) Edgar Akhmadeev 2020.06.19 00:56 #82 誰もがトピックが使い果たされたと思ったが、その後...構造体の配列に対してQuickSort ソートアルゴリズムをやり直しました。要するに、構造の配列をソートするための単純な配列ソートアルゴリズムの直接的な適用は、大量のデータの「物理的な」移動につながるということです。これを回避するために、すべての順列が作成されるインデックステーブルを使用しました。同時に、他のコード最適化を使用しました。さまざまなタイプの普遍性を維持するために、fxsaberのマクロラッパーを使用しました。その結果、MqlRates [30000]配列を8フィールドでソートするには、14900ミリ秒ではなく約3600ミリ秒かかりました。それは4倍以上の加速です。ソート結果を注意深くチェックしなかったので、ベータテスターに当てはめてください。ありがとう:もちろん、ユニバーサルコードのfxsaber。 // QSort.mq5 #property copyright "(c)2020 Edgar Akhmadeev, fxsaber" #property link "https://www.mql5.com/en/users/dali" #property strict #property version "1.00" // 2020.06.18 #define MAX_SIZE 30000 MqlRates Rates[]; int RatesIdx[]; // Сортировка массива структур и указателей на объекты по (под-) полю/методу. #define ArraySortStruct(T, ARRAY, FIELD) \ { \ class SORT \ { \ private : \ static void Swap( T &Array[], const int i, const int j ) \ { \ const T Temp = Array[i]; \ \ Array[i] = Array[j]; \ Array[j] = Temp; \ \ return ; \ } \ \ static int Partition( T &Array[], const int Start, const int End ) \ { \ int Marker = Start; \ \ for ( int i = Start; i <= End; i++) \ if (Array[i]. ##FIELD <= Array[End]. ##FIELD) \ { \ SORT::Swap(Array, i, Marker); \ \ Marker++; \ } \ \ return (Marker - 1 ); \ } \ \ static void QuickSort( T &Array[], const int Start, const int End ) \ { \ if (Start < End) \ { \ const int Pivot = Partition(Array, Start, End); \ \ SORT::QuickSort(Array, Start, Pivot - 1 ); \ SORT::QuickSort(Array, Pivot + 1 , End); \ } \ \ return ; \ } \ \ public : \ static void Sort( T &Array[], int Count = WHOLE_ARRAY , const int Start = 0 ) \ { \ if (Count == WHOLE_ARRAY ) \ Count = :: ArraySize (Array); \ \ SORT::QuickSort(Array, Start, Start + Count - 1 ); \ \ return ; \ } \ }; \ \ SORT::Sort(ARRAY); \ } #define StructArraySort(T, ARRAY, INDEX, FIELD) { \ class SORT { \ private : \ static void \ Swap( int &Index[], const int i, const int j) { \ const int idx = Index[i]; \ Index[i] = Index[j]; \ Index[j] = idx; \ return ; \ } \ \ static int \ Partition(T &Array[], int &Index[], const int Start, const int End) { \ int Marker = Start; \ \ for ( int i = Start; i <= End; ++i) \ if ((i == End) || (Array[i]. ##FIELD <= Array[End]. ##FIELD)) { \ if (i != Marker) \ SORT::Swap(Index, i, Marker); \ ++Marker; \ } \ \ return Marker - 1 ; \ } \ \ static void \ QuickSort(T &Array[], int &Index[], const int Start, const int End) { \ const int Pivot = Partition(Array, Index, Start, End); \ if (Start < Pivot - 1 ) \ SORT::QuickSort(Array, Index, Start, Pivot - 1 ); \ if (Pivot + 1 < End) \ SORT::QuickSort(Array, Index, Pivot + 1 , End); \ } \ \ public : \ static void \ Sort(T &Array[], int &Index[], int Count = WHOLE_ARRAY , const int Start = 0 ) { \ if (Count == WHOLE_ARRAY ) \ Count = :: ArraySize (Array); \ \ SORT::QuickSort(Array, Index, Start, Start + Count - 1 ); \ } \ }; \ \ SORT::Sort(ARRAY, INDEX); \ } #define StructArrayIndex(T, ARRAY, INDEX) { \ class IDX { \ public : \ static void \ Idx(T &Array[], int &Index[]) { \ int cnt = ArraySize (Array); \ ArrayResize (Index, cnt); \ for ( int i = cnt - 1 ; i >= 0 ; --i) \ Index[i] = i; \ } \ }; \ \ IDX::Idx(ARRAY, INDEX); \ } void OnStart () { int cnt = CopyRates ( _Symbol , PERIOD_M1 , 0 , MAX_SIZE, Rates); Print (cnt, " bars copied" ); uint start = GetTickCount (); ArraySortStruct( MqlRates , Rates, open); ArraySortStruct( MqlRates , Rates, high); ArraySortStruct( MqlRates , Rates, low); ArraySortStruct( MqlRates , Rates, close); ArraySortStruct( MqlRates , Rates, tick_volume); ArraySortStruct( MqlRates , Rates, real_volume); ArraySortStruct( MqlRates , Rates, time); ArraySortStruct( MqlRates , Rates, spread); Print ( "Test orig: " , GetTickCount () - start, " ms" ); start = GetTickCount (); StructArrayIndex( MqlRates , Rates, RatesIdx); StructArraySort( MqlRates , Rates, RatesIdx, open); StructArraySort( MqlRates , Rates, RatesIdx, high); StructArraySort( MqlRates , Rates, RatesIdx, low); StructArraySort( MqlRates , Rates, RatesIdx, close); StructArraySort( MqlRates , Rates, RatesIdx, tick_volume); StructArraySort( MqlRates , Rates, RatesIdx, real_volume); StructArraySort( MqlRates , Rates, RatesIdx, time); StructArraySort( MqlRates , Rates, RatesIdx, spread); Print ( "Test my: " , GetTickCount () - start, " ms" ); } UPD:明らかでない場合は、ソートされたリストの最上位の構造にアクセスします。MqlRates first = Rate [ RatesIdx [0] ]; 123456789 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
なぜ?そのためのトピックは別にあるのでしょうか?
グッドアイディア ))))
チキチキ...」というトピックを立ち上げるべき。" )))))
誰もがトピックが使い果たされたと思ったが、その後...
構造体の配列に対してQuickSort ソートアルゴリズムをやり直しました。要するに、構造の配列をソートするための単純な配列ソートアルゴリズムの直接的な適用は、大量のデータの「物理的な」移動につながるということです。これを回避するために、すべての順列が作成されるインデックステーブルを使用しました。同時に、他のコード最適化を使用しました。さまざまなタイプの普遍性を維持するために、fxsaberのマクロラッパーを使用しました。
その結果、MqlRates [30000]配列を8フィールドでソートするには、14900ミリ秒ではなく約3600ミリ秒かかりました。それは4倍以上の加速です。ソート結果を注意深くチェックしなかったので、ベータテスターに当てはめてください。
ありがとう:もちろん、ユニバーサルコードのfxsaber。
UPD:明らかでない場合は、ソートされたリストの最上位の構造にアクセスします。MqlRates first = Rate [ RatesIdx [0] ];