The difference between include file and the library file

 

Hi:

I am wondering what's the difference between using an include file and a library file.

As I understand, a library file is compiled and the code of an include file is included in the ea code and then compiled.

In term of the execution efficiency, which one is more efficient please?

Thanks

 
asuralm:

Hi:

I am wondering what's the difference between using an include file and a library file.

As I understand, a library file is compiled and the code of an include file is included in the ea code and then compiled.

In term of the execution efficiency, which one is more efficient please?

If the code is the same there is no difference.
 

Hi, As Raptor says the efficiency is the same if the code is the same.

In terms of code there are some differences:

Ive found that if you write functions with reference parameters they don't work if called in a library.

Also if you try to write fancy wrapper functions around OrderSend, OrderSelect etc (eg that automatically log/manage errors in one place,) then if they are called in a library they they dont work as expected.

So I just use include files, to avoid any more 'features' of MQ4 ...

 

Hmm, because MQ4 function calls behave differently, I got to wondering about performance ...

It turns out that function calls from the main program to the library are over twice as slow ...

Probably doesnt make much difference in the real world though.

On my VM, the Library functions take about 8.6 seconds for 50 million calls, compared to 3.6 seconds for local functions.

However in the scheme of things proably wont add more than a minute or so to a large back test.

I think performance is the least of the problems with mq4 library modules.


MAIN

#import "libtest.ex4"
void vfun2();
int ifun2();
#import

int start()
 {

   
   Alert("begin");


   int n = 49999999;
     // n = 50;
      
   int t = GetTickCount();
   int t2;
   bool test;
   int i;
   
   for( i = 0 ; i < n ; i++ ) {
   }
   t2 = GetTickCount();
   Alert(" Baseline "+n+" ticks:"+(t2-t));


   t = GetTickCount();
   for( i = 0 ; i < n ; i++ ) {
      vfun1();
   }
   t2 = GetTickCount();
   Alert("Void Local Call "+n+" ticks:"+(t2-t));

   t = GetTickCount();
   for( i = 0 ; i < n ; i++ ) {
      ifun1();
   }
   t2 = GetTickCount();
   Alert("Int Local Call "+n+" ticks:"+(t2-t));


   t = GetTickCount();
   for( i = 0 ; i < n ; i++ ) {
      vfun2();
   }
   t2 = GetTickCount();
   Alert("Void Library call "+n+" ticks:"+(t2-t));

   t = GetTickCount();
   for( i = 0 ; i < n ; i++ ) {
      ifun2();
   }
   t2 = GetTickCount();
   Alert("Int Library call "+n+" ticks:"+(t2-t));
}

void vfun1()
{
}
int ifun1()
{
   return(1);
}

LIBRARY

#property library

void  vfun2()
{
}

int  ifun2()
{
   return(2);
}
 
ydrol:

Hmm, because MQ4 function calls behave differently, I got to wondering about performance ...

It turns out that function calls from the main program to the library are over twice as slow ...

Probably doesnt make much difference in the real world though.

On my VM, the Library functions take about 8.6 seconds for 50 million calls, compared to 3.6 seconds for local functions.

However in the scheme of things proably wont add more than a minute or so to a large back test.

I think performance is the least of the problems with mq4 library modules.


MAIN

LIBRARY




Thanks very much ydrol. That's exactly I want to know. I prefer the include file as well. If lib module is slower, then there is no need to use lib.

Don't know if the MT5 will work better.

 

Regarding the invocation speed, I would not bother if the call costs additional 100ns. You won't cycle the external method, unless you are a very inexperienced designer.

Regarding other aspects, the library is encapsulated, so it does not interfere with future modification of your code, unlike the include-file.

If you have a compile-time error caused by the include file, you get confusing messages from the compiler.

If you use a versioning system, it is sometimes hard to guess which version (of the include file) was included to a binary.

The only place I prefer the include-file over a library is if the shared code needs to call back a local method, which obviously cannot be accessed by a library.

 
Ovo:

Regarding the invocation speed, I would not bother if the call costs additional 100ns. You won't cycle the external method, unless you are a very inexperienced designer.

Regarding other aspects, the library is encapsulated, so it does not interfere with future modification of your code, unlike the include-file.

If you have a compile-time error caused by the include file, you get confusing messages from the compiler.

If you use a versioning system, it is sometimes hard to guess which version (of the include file) was included to a binary.

The only place I prefer the include-file over a library is if the shared code needs to call back a local method, which obviously cannot be accessed by a library.


compile errors have the correct filename/linenumber when using include files.

Pass by reference doesnt work for imported functions.

Imported functions do not play nice with some OrderXXXX functions. (ie if you try to write a nice wrapper library around the OrderXXX functions then they might not work properly).

 
ydrol:

compile errors have the correct filename/linenumber when using include files.

Pass by reference doesnt work for imported functions.

Imported functions do not play nice with some OrderXXXX functions. (ie if you try to write a nice wrapper library around the OrderXXX functions then they might not work properly).


If something does not play "nice", it is probably buggy, though I have never spotted the problem you described. You may help other coders if you share the experience and specify what problem you encountered exactly.

Pass by reference has been working for me. What does output the following code in your environment?

#import "cp.ex4"
        void changePar(int par[]);
#import

int start() {
        int par[] = {0};
        changePar(par);
        Print("value after return is ", par[0]);
}

library cp.mq4

#property library

void changePar(int &par[]) {
        par[0] = 2;
        return;
}
 

Hi, Yes, Pass By reference works with arrays but not with normal variables. ( https://www.mql5.com/en/forum/145735 ), I think if you just want to pass a scalar variable by reference its a hack to make it into an array and then pass it. Yes its a hack that works, but it should be clear that's the hack I was talking about :)

Re OrderXX functions, I'll knock up an example when I get the chance, I basically spent some time creating wrappers around the OrderXXX functions (so all logging and retry behaviour is in one place ), however my wrapper around OrderSelect would not appear to select the order when it was called as an imported funtion.

 

Oh, I got your point. Nevertheless I'd call it a construction, rather than a hack, it is quite in favour with the docs in this case.

 
A documented bug is a feature :) Yes it's in agreement with DLLs, but I think that scalar pass by rerefence should work between modules written in the same source language. But just my opinion :)
Reason: