Nikolai Semko:
我想和程序员们分享一个意想不到的、简单而有用的发现。
四舍五入的功能。
已经证明是非常缓慢的。为了将四舍五入的过程加快4-5倍(根据我在MQL5中的测试),你可以用一个简单的替代方法来取代这些函数。
由于这些函数经常被用于大型和嵌套的循环中,性能的提高可以是相当显著的。
可能,调用一个函数的 事实是相当耗时的(存储不同的数据、地址等)。而在这种情况下,你可以不使用功能。
附有性能测试的脚本文件。
只有我与这句话
y=round(x); -> y=(int)(x+0.5);
我不同意这句话。根据数学规则,如果小数部分小于0.5,则四舍五入到下边。但如果你把0.5加到45.27,就会四舍五入到较高的位置。
Alexey Viktorov:
只是我不同意这句话。
我不同意。根据数学规则,如果小数部分小于0.5,则向下舍入。但如果你把0.5加到45.27,就会四舍五入到较高的位置。
#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)," микросекунд"); } //+------------------------------------------------------------------+
Alexey Viktorov:
我是唯一有这句话的人。
不同意。根据数学规则,如果小数部分小于0.5,则向下舍入。但如果你把0.5加到45.27,它就会被四舍五入到较高的位置。
拿着它去看看怎么样?)))int(45.27 + 0.5)怎么会得出46?同样的45人将被保留。
Lilita Bogachkova:
我不是在谈论速度。
Nikolai Semko:
你一定很困惑。我特意在例子中插入了一个检查码。
如果我错了,那么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)," микросекунд"); } //+------------------------------------------------------------------+
Ihor Herasko:
检查一下怎么样?)))int(45.27 + 0.5)怎么会得出46?同样的45人将被保留。
我同意,我失去了思考的方向。我把它收回...
Lilita Bogachkova:
这很简单。编译器忽略了这个命令。但有趣的是,如果阵列没有事先填充数据,速度会发生变化
并填充它
y0[i]+=0; // !!!!!!!!!!!!!!
因为它不会改变任何东西。数组仍未被初始化。看起来,已经初始化的数组访问速度更快。在第一种情况下,初始化是在计算t1时在第二个循环中进行的,所以t1比t2要大。而在第二种情况下,初始化发生在第一个循环中。因此,t1和t2是相同的。
我觉得 "#define "更方便
#define _floor(x) (int)((x)) #define _ceil(x) (int)((x)+(1)) #define _round(x) (int)((x)+(0.5))
你为什么不投向长?虽然你也可以溢出它,但溢出一个Int更容易。
我想和程序员们分享一个意想不到的、简单而有用的发现。
四舍五入的功能。
已经证明是非常缓慢的。为了将四舍五入的过程加快4-5倍(根据我在MQL5中的测试),你可以用一个简单的替代方法来取代这些函数。
由于这些函数经常被用于大型和嵌套的循环中,性能的提高可以是相当显著的。
可能,调用一个函数的 事实是相当耗时的(存储不同的数据、地址等)。而在这种情况下,你可以不使用功能。
附带性能测试的脚本文件。