意外でシンプルで便利な発見をプログラマーと共有したい。
丸め機能です。
非常に遅いことが証明されている。丸め処理を4-5倍速くするには(MQL5でテストしたところ)、これらの関数を単純な代替関数に置き換えることができます。
これらの関数は大規模なループやネストされたループで使用されることが多いため、性能向上は非常に大きなものとなります。
おそらく、関数を呼び出す こと自体にかなりの時間(異なるデータ、アドレスの保存など)がかかっているのだろう。そしてこの場合、機能はなくても大丈夫です。
パフォーマンステストのスクリプトファイルを添付します。
このセリフで私だけが
y=round(x); -> y=(int)(x+0.5);
この台詞には納得がいきません。数学のルールでは、端数部分が0.5より小さい場合、低い方に丸める。しかし、45.27に0.5を足すと、高い方に丸められます。
ただ、その台詞には納得がいきません。
納得がいきません。数学のルールでは、端数が0.5未満になると切り捨てになります。しかし、45.27に0.5を足すと、高い方に丸められます。
#define MUL(x) ((x)+(0.5)) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ulong t0,t1,t2,t3; int y0[],y1[],y2[]; ArrayResize(y0,10000000); ArrayResize(y1,10000000); ArrayResize(y2,10000000); double x=1.45; for(int i=0;i<10000000;i++) { if ((int)(x+0.5)!=(int)round(x)) Print("ой...",x); x+=0.27; y0[i]+=0; y1[i]+=0; y2[i]+=0; } Print("y0[]: ",y0[9999999]," / y1[]: ",y1[9999999]," / y2[]: ",y2[9999999]); x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y0[i]=(int)MathRound(x); x+=0.27; } t1=GetMicrosecondCount()-t0; Print("y0[]: ",y0[9999999]); x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y1[i]=(int)(x+0.5); x+=0.27; } t2=GetMicrosecondCount()-t0; Print("y1[]: ",y1[9999999]); x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y2[i]=(int)MUL(x); x+=0.27; } t3=GetMicrosecondCount()-t0; Print("y2[]: ",y2[9999999]); Print("Цикл округления 10 000 000 раз: (round) = ",IntegerToString(t1)," альтернатива с (int) = ",IntegerToString(t2)," альтернатива с (#define) = ",IntegerToString(t3)," микросекунд"); } //+------------------------------------------------------------------+
その台詞は私一人です。
は納得いかない。数学のルールでは、端数が0.5未満になると切り捨てになります。しかし、45.27に0.5を足すと、高い方に丸められます。
持ってみて確認してみてはいかがでしょうか。)))int(45.27 + 0.5)で46はどうなる?同じ45が残ります。
スピードの話じゃないんです。
戸惑っているのでは?例ではあえてチェックコードを挿入しています。
というのは、間違っていたら、Print("oops...",x) 文が実行されるからです。
試してみてください-大丈夫です。
それにしても、あらかじめ配列にデータを入れておかないと、速度が変わって しまうのは面白いですね
#define _round(x) (int)((x)+(0.5)) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ulong t0,t1,t2; int y0[],y1[]; ArrayResize(y0,10000000); double x=1.45; for(int i=0;i<10000000;i++) { if ((int)(x+0.5)!=(int)round(x)) Print("ой...",x); x+=0.27; y0[i]+=0; // !!!!!!!!!!!!!! } x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y0[i]=(int)(x+0.5); x+=0.27; } t1=GetMicrosecondCount()-t0; x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y0[i]=_round(x); x+=0.27; } t2=GetMicrosecondCount()-t0; Print("Цикл округления 10 000 000 раз: с (int) = ",IntegerToString(t1)," с (#define) = ",IntegerToString(t2)," микросекунд"); } //+------------------------------------------------------------------+
で埋め尽くされています。
#define _round(x) (int)((x)+(0.5)) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ulong t0,t1,t2; int y0[],y1[]; ArrayResize(y0,10000000); double x=1.45; for(int i=1;i<10000000;i++) { if ((int)(x+0.5)!=(int)round(x)) Print("ой...",x); x+=0.27; y0[i]+=1; // !!!!!!!!!!!!!! } x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y0[i]=(int)(x+0.5); x+=0.27; } t1=GetMicrosecondCount()-t0; x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y0[i]=_round(x); x+=0.27; } t2=GetMicrosecondCount()-t0; Print("Цикл округления 10 000 000 раз: с (int) = ",IntegerToString(t1)," с (#define) = ",IntegerToString(t2)," микросекунд"); } //+------------------------------------------------------------------+
チェックしてみてはいかがでしょうか。)))int(45.27 + 0.5)で46はどうなる?同じ45が残ります。
そうですね、思考が途切れてしまいました。撤回する...
それでも、あらかじめ配列にデータを入れておかないと、速度が変わって しまうのは面白いですね
を充填してください。
y0[i]+=0; // !!!!!!!!!!!!!!
私は「#define」の方が便利だと思います。
#define _floor(x) (int)((x)) #define _ceil(x) (int)((x)+(1)) #define _round(x) (int)((x)+(0.5))
なぜロングにキャストしないのか?混雑することもありますが、Intの混雑はかなり緩和されます。

- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
意外でシンプルで便利な発見をプログラマーと共有したい。
丸め機能です。
非常に遅いことが証明されている。丸め処理を4-5倍速くするには(MQL5でテストしたところ)、これらの関数を単純な代替関数に置き換えることができます。
これらの関数は大規模なループやネストされたループで使用されることが多いため、性能向上は非常に大きなものとなります。
おそらく、関数を呼び出す こと自体にかなりの時間(異なるデータ、アドレスの保存など)がかかっているのだろう。そしてこの場合、機能はなくても大丈夫です。
パフォーマンステストを行ったスクリプトのファイルを添付します。