MQL4およびMQL5でDigits()をバイパスして任意の数値(引用符だけでなく)の小数点以下桁数を取得 - ページ 14 1...78910111213141516171819202122 新しいコメント fxsaber 2018.12.07 14:12 #131 構造体の配列(sizeof(int)の倍数の長さ)をint[]配列と相互変換する高速な実装について、ブレインストーミングを行うことはできますか? 実用的な用途としては、リソースを介した高速なデータ交換が挙げられます。私のバリアントは 普遍的すぎるから遅くなるんだ。 MT5で登場した機能 StructToCharArray CharArrayToStruct MT4には存在しませんし、おそらく今後も存在しないでしょう。だから、これらの機能がある場合とない場合(役に立つ場合)で問題を解決しなければならない。 この結果は、ここのフォーラムの多くのユーザーにとって有益なものとなることでしょう。 この問題に対する私の解決策で、ブレインストーミングのための非常にシンプルなテンプレートを書きました。 // Решения задачи: https://www.mql5.com/ru/forum/287618/page14#comment_9806429 #define BENCH(A) \ { \ const ulong StartTime = GetMicrosecondCount(); \ A; \ Print("Time[" + #A + "] = " + (string)(GetMicrosecondCount() - StartTime)); \ } // Инициализация исходных данных int InitData( MqlTick &Ticks[], const int Amount = 1 e6, const double Price = 1.2345) { const int Size = ArrayResize(Ticks, Amount); for (int i = 0; i < Size; i++) Ticks[i].bid = Price; return(Size); } MqlTick TicksIn[]; // Массив с исходными данными. const int Init = InitData(TicksIn); // Инициализировали его. // Проверка, что два массива совпадают. bool IsCompare( const MqlTick &Ticks1[], const MqlTick &Ticks2[] ) { const int Size = ArraySize(Ticks1); bool Res = (Size == ArraySize(Ticks2)); for (int i = 0; (i < Size) && Res; i++) Res = (Ticks1[i].bid == Ticks2[i].bid); return(Res); } void OnStart() { MqlTick TicksOut[]; int Array[]; BENCH(TicksToIntArray_fxsaber1(TicksIn, Array)); // Замерили конвертацию MqlTick[] -> int[]. BENCH(IntArrayToTicks_fxsaber1(Array, TicksOut)); // Замерили конвертацию int[] -> MqlTick[]. Print(IsCompare(TicksIn, TicksOut)); // Убедились, что тики на входе и выходе совпадают. } // Варианты реализаций /***********************************************/ #include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280 template <typename T1, typename T2> int ArrayToArray( const T1 &Source[], T2 &Target[] ) { return(_ArrayCopy(Target, Source) / sizeof(T2)); } // Перевод массива тиков в массив int[]. int TicksToIntArray_fxsaber1( const MqlTick &Ticks[], int &Array[] ) { return(ArrayToArray(Ticks, Array)); } // Перевод массива int[] в массив тиков. int IntArrayToTicks_fxsaber1( const int &Array[], MqlTick &Ticks[] ) { return(ArrayToArray(Array, Ticks)); } /***********************************************/ 結果 Time[TicksToIntArray_fxsaber1(TicksIn,Array)] = 2036468 Time[IntArrayToTicks_fxsaber1(Array,TicksOut)] = 2253915 true fxsaber 2018.12.07 15:36 #132 別のバリアントtemplate <typename T> union INTEGER { T Data; int Integer[sizeof(T) / sizeof(int)]; }; // Перевод массива тиков в массив int[]. int TicksToIntArray_fxsaber2( const MqlTick &Ticks[], int &Array[] ) { INTEGER<MqlTick> TickInteger; const int Size1 = ArraySize(Ticks); const int Size2 = ArrayResize(Array, Size1 * sizeof(MqlTick) / sizeof(int)); int j = 0; for (int i = 0; (i < Size1) && (j < Size2); i++) { TickInteger.Data = Ticks[i]; j += ArrayCopy(Array, TickInteger.Integer, j); } return(j); } // Перевод массива int[] в массив тиков. int IntArrayToTicks_fxsaber2( const int &Array[], MqlTick &Ticks[] ) { INTEGER<MqlTick> TickInteger; const int Size1 = ArraySize(Array); const int Size2 = ArrayResize(Ticks, Size1 * sizeof(int) / sizeof(MqlTick)); int j = 0; for (int i = 0; (i < Size1) && (j < Size2); j++) { i += ArrayCopy(TickInteger.Integer, Array, 0, i, sizeof(MqlTick) / sizeof(int)); Ticks[j] = TickInteger.Data; } return(j); } 結果 Time[TicksToIntArray_fxsaber2(TicksIn,Array)] = 91967 Time[IntArrayToTicks_fxsaber2(Array,TicksOut)] = 79630 true 2番目の選択肢よりかなり速いもの。スピードアップの方法はないのでしょう。 Ilya Malev 2018.12.07 17:01 #133 構造体の配列 (sizeof(int) の倍数の長さ) を int[] 配列と相互変換する高速な実装はありますか? こんな感じ #property strict template< typename S, typename T > union UDT{ UDT(){for(int i=0;i<sizeof(S)/sizeof(T);i++)t[i]=0;} UDT(S&src){s=src;} UDT(T&src[],int k=0){for(int i=0;i<sizeof(S)/sizeof(T);i++)t[i]=src[i+k];} void to(S&dst){dst=s;} void to(T&dst[],int k=0){for(int i=0;i<sizeof(S)/sizeof(T);i++)dst[i+k]=t[i];} S s; T t[sizeof(S)/sizeof(T)];}; template< typename S, typename T > void StructToArray(S&src[],T&dst[]){ ArrayResize(dst,ArraySize(src)*(sizeof(S)/sizeof(T))); for(int i=0;i<ArraySize(dst)/(sizeof(S)/sizeof(T));i++){UDT<S,T>u(src[i]);u.to(dst,i*(sizeof(S)/sizeof(T)));}} template< typename S, typename T > void ArrayToStruct(T&src[],S&dst[]){ ArrayResize(dst,ArraySize(src)/(sizeof(S)/sizeof(T))); for(int i=0;i<ArraySize(dst);i++){UDT<S,T>u(src,i*(sizeof(S)/sizeof(T)));u.to(dst[i]);}} void OnStart() { MqlRates rates[],r2[]; int l[]; CopyRates(_Symbol,_Period,0,10,rates); for(int i=0;i<10;i++)printf("open=%f, high=%f, low=%f, close=%f, time=%s",rates[i].open,rates[i].high,rates[i].low,rates[i].close,TimeToStr(rates[i].time)); Print(""); StructToArray(rates,l); ArrayToStruct(l,r2); for(int i=0;i<ArraySize(r2);i++)printf("open=%f, high=%f, low=%f, close=%f, time=%s",r2[i].open,r2[i].high,r2[i].low,r2[i].close,TimeToStr(r2[i].time)); } fxsaber 2018.12.07 18:31 #134 Ilya Malev:こんな感じ。 https://www.mql5.com/ru/forum/287618/page14#comment_9807465 TicksToIntArray_fxsaber2 Time[TicksToIntArray(TicksIn,Array)] = 735252 IntArrayToTicks_fxsaber2 Time[IntArrayToTicks(Array,TicksOut)] = 591458 true https://www.mql5.com/ru/forum/287618/page14#comment_9808274 TicksToIntArray_antfx1 Time[TicksToIntArray(TicksIn,Array)] = 398796 IntArrayToTicks_antfx1 Time[IntArrayToTicks(Array,TicksOut)] = 296646 trueよくぞ言ってくれました。コードに手を入れてみます、ありがとうございました。 ArrayCopyは 本当に遅いみたいですね。 ZY 走るたびに、結果が大きく変わるんです。例えば、Testsの順番を変えると、ほとんどすべてが逆転してしまうんです。どうやら、より客観的な速度測定が必要なようです。 ファイル: StructToArray.mq5 6 kb Ilya Malev 2018.12.07 18:42 #135 あまり考えずに、デバッグもせずに、最初に思いついたことを書いたので、不具合も多いかもしれません。私自身、このような課題に遭遇したのは初めてです(労働組合とは幅広くお付き合いしていますが)。 Ilya Malev 2018.12.07 18:51 #136 fxsaber:ZZZさん、ArrayCopyはちょっと引き気味ですね。あるローカルなタスクで、少数のエレメントをコピーするような測定をしたことを覚えています。16要素まではforループの方がArrayCopyより はるかに速く、要素数が多くなるとArrayCopyの方が速くなりました。もちろん、ループを全く使わない最速のバリエーション(前ページの私の関数のように)もあります。 fxsaber 2018.12.07 19:12 #137 Ilya Malev:一番早いのは、ループを全く使わない方法です(前ページの私の関数のように)。理解できない。 Ilya Malev 2018.12.07 19:53 #138 fxsaber:理解できない。私が言いたいのは、for(int i=0; i<5; i++) dst[i]=src[i]; は dst[0]=src[0];dst[1]=src[1];dst[2]=src[2];dst[3]=src[3];dst[4]=src[4] より遅く動くということです。 というのは、ループ管理に関連する追加操作のことを考えれば、ごく当たり前のことです) そして、CopyArrayは、今確認したところ、両者よりもはるかに高速に動作します。もちろん状況にもよるのかもしれませんが。 Ilya Malev 2018.12.07 20:12 #139 はい、この方がずっと 速く動作します(可能な限りArrayCopyで 置き換え、その他は同じです)。 template< typename S, typename T > union UTS2{ UTS2(){for(int i=0;i<sizeof(S)/sizeof(T);i++)t[i]=0;} UTS2(S&src){s=src;} UTS2(T&src[],int k=0){ArrayCopy(t,src,0,k,sizeof(S)/sizeof(T));}//for(int i=0;i<sizeof(S)/sizeof(T);i++)t[i]=src[i+k];} void to(S&dst){dst=s;} void to(T&dst[],int k=0){ArrayCopy(dst,t,k,0,sizeof(S)/sizeof(T));}//for(int i=0;i<sizeof(S)/sizeof(T);i++)dst[i+k]=t[i];} S s; T t[sizeof(S)/sizeof(T)];}; template< typename S, typename T > void StructToArray2(S&src[],T&dst[]){ ArrayResize(dst,ArraySize(src)*(sizeof(S)/sizeof(T))); for(int i=0;i<ArraySize(dst)/(sizeof(S)/sizeof(T));i++){UTS2<S,T>u(src[i]);u.to(dst,i*(sizeof(S)/sizeof(T)));}} template< typename S, typename T > void ArrayToStruct2(T&src[],S&dst[]){ ArrayResize(dst,ArraySize(src)/(sizeof(S)/sizeof(T))); for(int i=0;i<ArraySize(dst);i++){UTS2<S,T>u(src,i*(sizeof(S)/sizeof(T)));u.to(dst[i]);}} だから、テストもせずに最初に思いついたことを書いたってばよ)) Igor Makanu 2018.12.07 20:19 #140 Ilya Malev:そして、CopyArrayは、今確認したところ、両方のオプションよりずっと速く動作するようです。もちろん状況次第なのかもしれませんが。Cish memmove()の原理でArrayCopy()を行った場合。ArrayCopy()の実行速度は、メモリの確保速度に依存すると思います。中間バッファのメモリがコピーできる状態であれば、ArrayCopy()は非常に速く実行されますが、メモリが確保されていない場合は、OSにメモリの確保を 要求するようになるでしょう。大きなデータ量でArrayCopy()を1回呼び出し、交換用のバッファメモリを準備し、次に小さなデータ量でArrayCopy()をループさせ、速度を測定してみるとよいでしょう。 1...78910111213141516171819202122 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
構造体の配列(sizeof(int)の倍数の長さ)をint[]配列と相互変換する高速な実装について、ブレインストーミングを行うことはできますか?
実用的な用途としては、リソースを介した高速なデータ交換が挙げられます。私のバリアントは 普遍的すぎるから遅くなるんだ。
MT5で登場した機能
MT4には存在しませんし、おそらく今後も存在しないでしょう。だから、これらの機能がある場合とない場合(役に立つ場合)で問題を解決しなければならない。
この結果は、ここのフォーラムの多くのユーザーにとって有益なものとなることでしょう。
この問題に対する私の解決策で、ブレインストーミングのための非常にシンプルなテンプレートを書きました。
結果
結果
2番目の選択肢よりかなり速いもの。スピードアップの方法はないのでしょう。
構造体の配列 (sizeof(int) の倍数の長さ) を int[] 配列と相互変換する高速な実装はありますか?
こんな感じ
こんな感じ。
よくぞ言ってくれました。コードに手を入れてみます、ありがとうございました。
ArrayCopyは 本当に遅いみたいですね。
ZY 走るたびに、結果が大きく変わるんです。例えば、Testsの順番を変えると、ほとんどすべてが逆転してしまうんです。どうやら、より客観的な速度測定が必要なようです。
ZZZさん、ArrayCopyはちょっと引き気味ですね。
あるローカルなタスクで、少数のエレメントをコピーするような測定をしたことを覚えています。16要素まではforループの方がArrayCopyより はるかに速く、要素数が多くなるとArrayCopyの方が速くなりました。もちろん、ループを全く使わない最速のバリエーション(前ページの私の関数のように)もあります。
一番早いのは、ループを全く使わない方法です(前ページの私の関数のように)。
理解できない。
理解できない。
私が言いたいのは、for(int i=0; i<5; i++) dst[i]=src[i]; は dst[0]=src[0];dst[1]=src[1];dst[2]=src[2];dst[3]=src[3];dst[4]=src[4] より遅く動くということです。
というのは、ループ管理に関連する追加操作のことを考えれば、ごく当たり前のことです)
そして、CopyArrayは、今確認したところ、両者よりもはるかに高速に動作します。もちろん状況にもよるのかもしれませんが。
はい、この方がずっと 速く動作します(可能な限りArrayCopyで 置き換え、その他は同じです)。
だから、テストもせずに最初に思いついたことを書いたってばよ))
そして、CopyArrayは、今確認したところ、両方のオプションよりずっと速く動作するようです。もちろん状況次第なのかもしれませんが。
Cish memmove()の原理でArrayCopy()を行った場合。
ArrayCopy()の実行速度は、メモリの確保速度に依存すると思います。中間バッファのメモリがコピーできる状態であれば、ArrayCopy()は非常に速く実行されますが、メモリが確保されていない場合は、OSにメモリの確保を 要求するようになるでしょう。
大きなデータ量でArrayCopy()を1回呼び出し、交換用のバッファメモリを準備し、次に小さなデータ量でArrayCopy()をループさせ、速度を測定してみるとよいでしょう。