Luta pela velocidade: QLUA vs MQL5 - por que o MQL5 é 50 a 600 vezes mais rápido?
Para comparar as linguagens MQL5 e QLUA, escrevemos vários testes que medem a velocidade de execução de operações básicas. Nos testes, usamos um computador com Windows 7 Professional 64 bits, MetaTrader 5 build 1340 e QUIK versão 7.2.0.45.
Os resultados são apresentados numa tabela cujos valores são expressos em milissegundos (quanto menos tempo, melhor)
# | Nome do script de teste | MQL5, ms | QLUA, ms | Vantagens de MQL5 |
---|---|---|---|---|
1 | TestFloat | 3 969 | 273 391 | 69 vezes |
2 | TestArrays | 375 | 230 768 | 615 vezes |
3 | TestFibo | 1 125 | 61 110 | 55 vezes |
4 | TestPiCalculated | 2 328 | 183 812 | 79 vezes |
5 | TestQuickSort | 2 031 | 211 279 | 104 vezes |
6 | TestAckermann | 828 | 64 541 | 78 vezes |
As comparações mostram que MQL5 é 50 a 600 vezes mais rápido do que QLUA em operações básicas de qualquer linguagem de programação. Isso é obtido devido ao fato de que MQL5 é uma linguagem compilada fortemente tipada em 32/64 bits, em oposição à QLUA, que é dinâmica.
O que isso dá ao trader? Capacidade de calcular rapidamente grandes matrizes de dados (praticamente ilimitadas no MetaTrader 5) e tomar decisões mais rapidamente.
Isso é apenas um teste da funcionalidade básica. Mas por trás da fachada das linguagens está sua API, que para nenhuma delas é simples. MQL5, sendo uma linguagem aplicada para uma plataforma de negociação, contém centenas de funções especializadas para acessar/processar informações de mercado e interagir com todos os componentes do terminal.
É importante que a MQL5 não seja anexada como complemento do sistema existente, mas, pelo contrário, seja o elo central da plataforma. Todos os processos no terminal de negociação são desenvolvidos para atender às necessidades dos desenvolvedores de robôs de negociação. Isso torna mais rápido o acesso aos dados internos da plataforma e cria um canal direto para operações de negociação.TestFloat - Velocidade de execução de operações com números reais
Código em MQL5
//+------------------------------------------------------------------+ //| TestFloat.mq5 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" //--- #define MAX_SIZE 35000 //--- double f0=0; double f1=123.456789; double f2=98765.12345678998765432; double f3=12345678943.98; //--- //+------------------------------------------------------------------+ //| Função OnStart | //+------------------------------------------------------------------+ int OnStart() { uint tick_count,res; //--- teste tick_count=GetTickCount(); TestFloat(); res=GetTickCount()-tick_count; Print("Test float time=",res," ms"); Print("Result=",f0); //--- retorna quanto tempo foi gasto na execução do teste, em milissegundos return((int)res); } //+------------------------------------------------------------------+ //| Função de teste | //+------------------------------------------------------------------+ void TestFloat() { for(int i=0;i<MAX_SIZE;i++) for(int j=0;j<MAX_SIZE;j++) { f0=f0+(f1/(i+1))-f2+(f3*i); } } //+------------------------------------------------------------------+
Código em LUA
-- TestFloat f0=0.0 f1=123.456789 f2=98765.12345678998765432 f3=12345678943.98 MAX_SIZE=35000 function Start() local t=os.clock() TestFloat() local res=(os.clock()-t)*1000 -- os resultados de execução devem ser inseridos aqui check=f0 message("TestFloat time=" ..res.." ms\n check="..tostring(check)); end function TestFloat() -- num loop chegamos até um valor 1 vez mais pequeno que MAX_SIZE MAX_SIZE=MAX_SIZE-1 for i=0, MAX_SIZE do for j=0, MAX_SIZE do f0=f0+(f1/(i+1))-f2+(f3*i); end end end -- executamos o script Start()
TestArrays - Testando velocidade de acesso a elementos da matriz
Código em MQL5
//+------------------------------------------------------------------+ //| TestArrays.mq5 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" //--- #define MAX_SIZE 32000 //--- int x[MAX_SIZE],y[MAX_SIZE]; //+------------------------------------------------------------------+ //| Função OnStart | //+------------------------------------------------------------------+ int OnStart() { int i,k; uint tick_count,res; //--- teste tick_count=GetTickCount(); for(i=0;i<MAX_SIZE;i++) x[i]=i+1; for(k=0;k<MAX_SIZE;k++) for(i=MAX_SIZE-1; i>=0; i--) y[i]+=x[i]; long check=0; for(i=0;i<MAX_SIZE;i++) { check+=y[i]; } res=GetTickCount()-tick_count; Print("TestArrays time=",res," ms"); Print("check=",check); //--- retorna quanto tempo foi gasto na execução do teste, em milissegundos return((int)res); } //+------------------------------------------------------------------+
Código em LUA
-- TestArrays function Start() MAX_SIZE=32000 x={} y={} local start=os.clock() for i=1,MAX_SIZE,1 do x[i]=i y[i]=0 end y[MAX_SIZE]=0 for k=1,MAX_SIZE,1 do for i=MAX_SIZE, 1,-1 do y[i]=y[i]+x[i] end end local res=(os.clock()-start)*1000 -- número de controle local check=0 for k=1,MAX_SIZE,1 do check=check+y[k] end message("Time = "..res.." ms\n check=".. check) end -- executamos o script Start()
TestFibo - Calculando o sequenciamento da série Fibonacci
Código em MQL5
//+------------------------------------------------------------------+ //| TestFibo.mq5 | //| Copyright 2010, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" //--- #define MAX_SIZE 40 long fib[MAX_SIZE]; //+------------------------------------------------------------------+ //| Função OnStart | //+------------------------------------------------------------------+ void OnStart() { int i; uint res; //--- teste res=GetTickCount(); for(i=0;i<MAX_SIZE;i++) fib[i]=TestFibo(i); res=GetTickCount()-res; Print("TestFibo time=",res," ms"); Print("Fibo[39]=",fib[39]); } //+------------------------------------------------------------------+ //| Função de teste | //+------------------------------------------------------------------+ long TestFibo(long n) { if(n<2) return(1); //--- return(TestFibo(n-2)+TestFibo(n-1)); } //+------------------------------------------------------------------+
Código em LUA
-- TestFibo MAX_SIZE=40 fib={} function Start() start=os.clock() for i=0,MAX_SIZE-1 do fib[i]=TestFibo(i) end res=(os.clock()-start)*1000 message("TestFibo time="..res.." ms\n Fibo[39]="..fib[39]) end function TestFibo(n) if n<2 then return(1) else return(TestFibo(n-2)+TestFibo(n-1)) end end -- executamos o script Start()
TestPiCalculated - Calculando 22 000 dígitos de Pi
Código em MQL5
//+------------------------------------------------------------------+ //| TestPiCalculated.mq5 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" //--- #define MAX_SIZE 22000 //--- nesta string colocamos o valo do número PI string str; int a[(MAX_SIZE/4+1)*14]; //+------------------------------------------------------------------+ //| Função OnStart | //+------------------------------------------------------------------+ int OnStart() { uint tick_count,res; //--- teste tick_count=GetTickCount(); PiCalculate(MAX_SIZE); res=GetTickCount()-tick_count; Print("TestPiCalculated time=",res," ms"); Print("Pi=",StringSubstr(str,0,16)); //--- retorna quanto tempo foi gasto na execução do teste, em milissegundos return((int)res); } //+------------------------------------------------------------------+ //| Função de teste | //+------------------------------------------------------------------+ void PiCalculate(const int digits) { int d = 0,e,b,g,r; int c = (digits/4+1)*14; int f = 10000; //--- for(int i=0;i<c;i++) a[i]=20000000; //--- while((b=c-=14)>0) { d=e=d%f; while(--b>0) { d = d * b + a[b]; g = (b << 1) - 1; a[b]=(d%g)*f; d/=g; } r=e+d/f; if(r<1000) { if(r>99) str+="0"; else { if(r>9) str+="00"; else str+="000"; } } str+=IntegerToString(r); } } //+------------------------------------------------------------------+
Código em LUA
-- TestPiCalculated -- quantidade de dígitos do número Pi que usaremos ao calcular MAX_SIZE=22000 -- nesta string colocamos o valor do número Pi str="" a={} function OnStart() start=os.clock() PiCalculate(MAX_SIZE) -- tempo de cálculo do número Pi em milissegundos res=(os.clock()-start)*1000 message("TestPiCalculated time=" .. res .." ms\n\n Pi="..string.sub(str,1,16)) -- exibimos 16 dígitos end function PiCalculate(digits) d = 0 c = (math.floor(digits/4)+1)*14 -- math.floor() -divisão inteira baseada num exemplo da documentação de LUA f = 10000 for i=0,c do a[i]=20000000 end c=c-14 b=c while b>0 do e=d%f d=e while b-1>0 do b=b-1 d = d * b + a[b] g = (b * 2) - 1 a[b]=(d%g)*f d=math.floor(d/g) -- math.floor(d/g) - divisão inteira baseada num exemplo da documentação de LUA end r=e+math.floor(d/f) -- math.floor(d/f) - divisão inteira baseada num exemplo da documentação de LUA if r<1000 then if(r>99) then str=str .. "0" else if(r > 9) then str=str .. "00" else str=str .. "000" end end end str=str .. string.format("%d",r) c=c-14 b=c end end -- executamos o script OnStart()
Testando a velocidade de classificação rápida de matriz
Código em MQL5
//+------------------------------------------------------------------+ //| TestQuickSort.mq5 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" //--- classificaremos uma matriz com um tamanho de 16 milhões de elementos #define MAX_SIZE 16000000 //--- int array[MAX_SIZE]; //+------------------------------------------------------------------+ //| Função OnStart | //+------------------------------------------------------------------+ void OnStart() { uint tick_count,res; for(int i=0;i<MAX_SIZE;i++) array[i]=i%100; tick_count=GetTickCount(); QuickSort(array,0,MAX_SIZE-1); res=GetTickCount()-tick_count; Print("TestQuickSort time=",res," ms"); for(int i=1;i<MAX_SIZE;i++) if(array[i]<array[i-1]) { Print("Array not sorted"); break; } } //+------------------------------------------------------------------+ //| Função de classificação rápida | //+------------------------------------------------------------------+ void QuickSort(int &arr[],int left,int right) { int i=left; int j=right; int center=arr[(i+j)/2]; int x; //--- while(i<=j) { while(arr[i]<center && i<right) i++; while(arr[j]>center && j>left) j--; if(i<=j) { x=arr[i]; arr[i]=arr[j]; arr[j]=x; i++; j--; } } if(left<j) QuickSort(arr,left,j); if(right>i) QuickSort(arr,i,right); } //+------------------------------------------------------------------+
Código em LUA
-- TestQuickSort - classificaremos uma matriz com um tamanho de 16 milhões de elementos MAX_SIZE=16000000 array={} function Start() for i=0,MAX_SIZE-1 do array[i]=i%100 end start=os.clock() QuickSort(array,0,MAX_SIZE-1) res=(os.clock()-t)*1000 message("TestQuickSort time=" .. res .. " ms") for i=1,MAX_SIZE-1 do if array[i]<array[i-1] then message("Array not sorted"); break; end end end function QuickSort(arr,left,right) i=left j=right center=arr[math.floor((i+j)/2)] while i<=j do while(arr[i]<center and i<right) do i=i+1 end while(arr[j]>center and j>left) do j=j-1 end if i<=j then x=arr[i] arr[i]=arr[j] arr[j]=x i=i+1 j=j-1 end end if left<j then QuickSort(arr,left,j) end if right>i then QuickSort(arr,i,right) end end -- executamos o script Start()
TestAckermann - Testando recursão em funções
Código em MQL5
//+------------------------------------------------------------------+ //| TestAckermann.mq5 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2016, MetaQuotes Software Corp." #property link "http://www.mql5.com" //--- número de execuções da função de Ackermann no loop #define MAX_SIZE 120000 //+------------------------------------------------------------------+ //| Função OnStart | //+------------------------------------------------------------------+ void OnStart() { //--- número de controle uint check=0; //--- tempo de execução em milissegundos uint res=0; //--- teste res=GetTickCount(); for(int i=0;i<MAX_SIZE;i++) check+=Ackermann(1+i%3,1+i%5); res=GetTickCount()-res; Print("TestAckermann time=",res," ms"); Print("check=",check); //--- } //+------------------------------------------------------------------+ //| Função de teste | //+------------------------------------------------------------------+ int Ackermann(int m,int n) { if(m==0) return(n+1); if(n==0) return(Ackermann(m-1,1)); //--- return(Ackermann(m-1,Ackermann(m,(n-1)))); } //+------------------------------------------------------------------+
Código em LUA
-- TestAckermann MAX_SIZE=120000 function Start() local check=0 -- número de controle local start=os.clock() for i=1,MAX_SIZE do check=check+Ackermann(1+i%3,1+i%5); end local finish=os.clock() local time=(finish-start)*1000 message("TestAckermann time=".. time.." ms\n\n check="..check) end function Ackermann(m,n) if(m==0) then return(n+1) end if(n==0) then return(Ackermann(m-1,1)) end return(Ackermann(m-1,Ackermann(m,(n-1)))) end -- executamos o script Start()
Você pode baixar o arquivo de scripts completo e verificar os resultados por conta própria.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/4310
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso