帆布很酷! - 页 19

 
Renat Fatkhullin:

事实证明,我看的是网络生成频率,而不是输出频率。

这些是不同的数字,是彼此的倍数。

事实证明,我在计算网络生成频率(无输出)和输出频率(无生成)时有点错误

这里有一个更正确的版本。


我的处理器上的结果。

如果你纯粹通过生成一帧200个平滑的圆圈而不输出来计算时间,那么它发生的速度大约是每秒500帧。

形成一帧200个未平滑的圆圈,没有输出--大约1000帧。

图像(画布)输出本身(更新功能)的频率约为650 fps。

你真的很努力!

附加的文件:
 
Renat Fatkhullin:

小心(int)double或(double)int类型的大量转换,以及在一般的mat操作中混合使用int+double。

这给处理器带来了最疯狂的开销--就是这样一个昂贵的汇编命令。如果你用双数计算,就一直用双数计算,不要换成整数类型。

像cvtsi2sd/cvttsd2si这样的命令非常长。在"最慢的x86指令"一文中的一个小提示,小人第2

谢谢你写了一篇非常有价值的文章。


但说实话,我不明白为什么在这个简单的脚本中会这样。

#define  Num 1000000 
void OnStart()
  {
    double arr[Num];
    for (int i=0;i<Num;i++) arr[i]=(double) rand()/(1+rand()%100); // инициализируем массив случайными числами double от 0.0 до 32767.0
    
    long sumL=0;
    
    ulong t1=GetMicrosecondCount();
    for (int i=0;i<Num;i++) sumL+=(long)arr[i]; // сумма long
    t1=GetMicrosecondCount()-t1;
    
    double sumD=0;
    
    ulong t2=GetMicrosecondCount();
    for (int i=0;i<Num;i++) sumD+=arr[i];      // сумма double
    t2=GetMicrosecondCount()-t2;  
    
    Print ("Сумма long   = "+ string(sumL)+ ", время суммирования "+string(t1)+" микросекунд");
    Print ("Сумма double = "+ DoubleToString(sumD)+ ", время суммирования "+string(t2)+" микросекунд");   
  }

将双数类型转换为长数后,长数之和比同一数组中没有转换的双数之和快得多。

2019.01.15 22:21:46.410 TestSpeedDoubleAndInt (NZDUSD,M5)       Сумма long   = 849290923,          время суммирования 748  микросекунд
2019.01.15 22:21:46.410 TestSpeedDoubleAndInt (NZDUSD,M5)       Сумма double = 849764484.23059070, время суммирования 1393 микросекунд
 

首先,应该看看汇编代码和极其简单的情况下的优化结果(超微合成学早已被误导)。很容易遇到一个理想的传送带实施案例。

其次,几乎没有人能够保证这个或那个代码将如何编译,以及它将需要多长时间来执行。

你只需在代码中多加一行/命令,速度就会有很大的变化。真正的 代码/数据很可能从L1/L2高速缓存中出来,仅此而已。

它对你的作用如何?在理论上/超级美学上,似乎整数命令对速度有帮助,但在实际代码中,它是一种消耗。因为有几十/几百倍的代码,没有对流,从整数计算到实数计算的不断跳转,优化受到限制。

 
Renat Fatkhullin:


为什么MQL4中任何类型的数组的初始化 都比MQL5中慢10倍以上?

 
Реter Konow:

为什么MQL4中任何类型的数组的初始化 都比MQL5中慢10倍以上?

因为那里的所有数组都是动态的,而且语言的速度要慢十倍。

 
这是个很酷的答案))。
因为慢了十倍))。
 

一个由数百条移动平均线组成的超快速指标,在Canvas上实现。

100条MA线(周期步骤10)-计算和在屏幕上显示的时间-4-7毫秒


1000行MA(周期步骤1)-计算和显示的时间-20-30毫秒。


我还没有对代码进行过多的测试。可能会有虫子。只对一个像素厚的条形图实施(它被强制到这个比例)。此外,屏幕刷新率也没有得到优化。所有的线条都经过计算,并在每一个刻度上完全输出。

#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164
#property indicator_chart_window

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
input int MA=1000;   // максимальный период скользящих средних
input int stepMa=10; // шаг скользящих средних

double  Close[];
long Total;
int Ma;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
   ChartSetInteger(0,CHART_SCALE,0,0);
   ChartSetInteger(0,CHART_FOREGROUND,true);
   CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);
   Total=SeriesInfoInteger(_Symbol,_Period,SERIES_BARS_COUNT);
   if (Total<(MA+W.BarsInWind)) Ma=(int)Total-1-W.BarsInWind; else Ma=MA;
   if (Ma<=0) Ma=1;
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[])
  {
   CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);
   Print("Время формирования кадра = "+(string)(nMA()/1000)+" миллискунд");
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      ChartSetInteger(0,CHART_SCALE,0,0);
      CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);
      Print("Время формирования кадра = "+(string)(nMA()/1000)+" миллискунд");
     }
  }
//+------------------------------------------------------------------+

ulong nMA()
  {
   ulong t=GetMicrosecondCount();
   int preY=0;
   Canvas.Erase();
   double S=0;
   for(int i=0;i<Ma; i++) S+=Close[i];

   for(int Per=Ma;Per>0;)
     {
      double s=S;
      uint Clr=Grad((double)Per/Ma);
      for(int x=0; x<W.BarsInWind;x++)
        {
         int Y=(int)(Canvas.Y(s/Per)-0.5);
         if(x>0) if(fabs(Y-preY)>1) Canvas.Line(x-1,preY,x,Y,Clr);
         else Canvas.PixelSet(x,Y,Clr);
         if((Ma+x)<ArraySize(Close)) s=s-Close[x+Ma-Per]+Close[Ma+x]; else break;
         preY=Y;
        }
      for(int j=0; j<stepMa; j++) if(Per>0){ S=S-Close[Ma-Per]; Per--;} else break;
     }
   Canvas.Update();
   return GetMicrosecondCount()-t;
  }
//+------------------------------------------------------------------+
uint Grad(double p)
  {
   static uint Col[6]={0xFF0000FF,0xFFFF00FF,0xFFFF0000,0xFFFFFF00,0xFF00FF00,0xFF00FFFF};
   if(p>0.9999) return Col[5];
   if(p<0.0001) return Col[0];
   p=p*5;
   int n=(int)p;
   double k=p-n;
   argb c1,c2;
   c1.clr=Col[n];
   c2.clr=Col[n+1];
   return ARGB(255,c1.c[2]+uchar(k*(c2.c[2]-c1.c[2])+0.5),
                   c1.c[1]+uchar(k*(c2.c[1]-c1.c[1])+0.5),
                   c1.c[0]+uchar(k*(c2.c[0]-c1.c[0])+0.5));
  }
//+------------------------------------------------------------------+
附加的文件:
MultiMA.mq5  9 kb
 
Nikolai Semko:

一个由数百条移动平均线组成的超快速指标,在Canvas上实现。

100行MA(周期步骤10)-计算和在屏幕上显示的时间-4-7毫秒


1000条MA线(周期步骤1) - 计算和显示的时间 - 20-30毫秒


酷,有了标准的指标,一切都会变得很糟糕

 
Maxim Dmitrievsky:

酷,标准指标会把它全部挂起来。

然后会有一英里的代码......

也许即使这样也只能用模板来做。我不知道一个指标主体中的指标线 数量有什么限制。

 
Nikolai Semko:

...

不知道对一个指标主体中的指标线 数量的限制。

有一个限度。最多可以做512个指标缓冲区 >>https://www.mql5.com/ru/docs/indicators

Документация по MQL5: Технические индикаторы
Документация по MQL5: Технические индикаторы
  • www.mql5.com
Все функции типа iMA, iAC, iMACD, iIchimoku и т.п., создают в глобальном кеше клиентского терминала копию соответствующего технического индикатора. Если копия индикатора с этими параметрами уже существует, то новая копия не создается, а увеличивается счетчик ссылок на данную копию. Эти функции возвращают хэндл соответствующей копии индикатора...