MQL equivalent to Python's None type? - page 8

 
fxsaber:

My test: the by_val works much faster than the by_ref.

Can you try by ref with const in by_ref?
int by_ref(const string &var){ return int(var) % 100; }
 
Amir Yacoby:
Can you try by ref with const in by_ref?
#define ITERATIONS 1000000

void OnStart()
{
   string Str = "1";
   
   for (int i = 0; i < 10; i++)
     Str += Str;
   
   for (int j = 0; j < 5; j++)
   {
     {
        ulong time = GetMicrosecondCount();
        ulong sum = 0;
        for(int i=0; i<ITERATIONS; i++){
           const string r = string(rand()) + Str;
           sum += by_ref(r);
        }
        time = GetMicrosecondCount() - time;
        printf("%s took %.3f milliseconds: sum=%dll", "by_ref", time/1000.0, sum);
     }{
        ulong time = GetMicrosecondCount();
        ulong sum = 0;
        for(int i=0; i<ITERATIONS; i++)
           sum += by_val(string(rand()) + Str);
        time = GetMicrosecondCount() - time;
        printf("%s took %.3f milliseconds: sum=%dll", "by_val", time/1000.0, sum);
     }
     
     Print("");
   }
}
//+------------------------------------------------------------------+

int by_ref(const string &var){ return int(var) % 100; }
int by_val(const string  var){ return int(var) % 100; }


by_ref took 15315.273 milliseconds: sum=-1000000ll
by_val took 16784.371 milliseconds: sum=-1000000ll

by_ref took 16005.445 milliseconds: sum=-1000000ll
by_val took 16408.359 milliseconds: sum=-1000000ll

by_ref took 14450.029 milliseconds: sum=-1000000ll
by_val took 15010.212 milliseconds: sum=-1000000ll

by_ref took 15458.176 milliseconds: sum=-1000000ll
by_val took 17585.525 milliseconds: sum=-1000000ll

by_ref took 16557.555 milliseconds: sum=-1000000ll
by_val took 15207.455 milliseconds: sum=-1000000ll
 
fxsaber:


Now its better. And if you remove the added operation for the ref, it might get faster.

I mean this line
const string r = string(rand()) + Str;
To
const string r; // out of loop

r = string(rand()) + Str; // in loop
Or like Nicholi did


 
fxsaber:

My test: the by_val works much faster than the by_ref.

Same here, which is why I don't use refs unless I need them.... It's not even about the speed it just makes passing args a pain in the !@#. 

You missed the float FLT_MAX

You're absolutely right! Thanks!

I forgot it was even a type in MQL... 😜 Honestly though, I don't recall ever actually seeing it used in an MQL program. 

#ifdef __MQL4__
#property strict
#endif 

#define NONE_DOUBLE  DBL_MAX
#define NONE_FLOAT   FLT_MAX
#define NONE_INT     INT_MAX
#define NONE_UINT    UINT_MAX
#define NONE_LONG    LONG_MAX
#define NONE_ULONG   ULONG_MAX
#define NONE_CHAR    CHAR_MAX
#define NONE_UCHAR   UCHAR_MAX
#define NONE_SHORT   SHORT_MAX
#define NONE_USHORT  USHORT_MAX
#define NONE_COLOR   clrNONE
#define NONE_DATETIME -1
#define NONE_POINTER NULL
#define NONE_STRING  "__NONE-*-*-STRING__"

class _NoneType
{
 public:
   static double   None(double _)     { return NONE_DOUBLE;}
   static float    None(float _)      { return NONE_FLOAT; }
   static int      None(int _)        { return NONE_INT;   }
   static uint     None(uint _)       { return NONE_UINT;  }
   static long     None(long _)       { return NONE_LONG;  }
   static ulong    None(ulong _)      { return NONE_ULONG; }
   static char     None(char _)       { return NONE_CHAR;  }
   static uchar    None(uchar _)      { return NONE_UCHAR; }
   static short    None(short _)      { return NONE_SHORT; }
   static ushort   None(ushort _)     { return NONE_USHORT;}
   static string   None(string _)     { return NONE_STRING;}
   static color    None(color _)      { return NONE_COLOR; }
   static datetime None(datetime _)   { return NONE_DATETIME;}
   template<typename T>
   static T        None(T _)          { return NONE_POINTER;}
};

#define NONE(T)  _NoneType::None((T)NULL)
 
Yes, passing by value copies the value to the stack
Passing by reference copies the reference to the stack - and adds some more indirect stuff.
 
nicholi shen:

Same here, which is why I don't use refs unless I need them.... It's not even about the speed it just makes passing args a pain in the !@#. 

You're absolutely right! Thanks!

I forgot it was even a type in MQL... 😜 Honestly though, I don't recall ever actually seeing it used in an MQL program. 

Why btw you choose not to use the IsNone(type) methods by fxsaber?
 
Amir Yacoby:
Why btw you choose not to use the IsNone(type) methods by fxsaber?

Great idea!

BTW, thanks fxsaber!


#ifdef __MQL4__
#property strict
#endif 

#define NONE_DOUBLE  DBL_MAX
#define NONE_FLOAT   FLT_MAX
#define NONE_INT     INT_MAX
#define NONE_UINT    UINT_MAX
#define NONE_LONG    LONG_MAX
#define NONE_ULONG   ULONG_MAX
#define NONE_CHAR    CHAR_MAX
#define NONE_UCHAR   UCHAR_MAX
#define NONE_SHORT   SHORT_MAX
#define NONE_USHORT  USHORT_MAX
#define NONE_COLOR   clrNONE
#define NONE_DATETIME -1
#define NONE_POINTER NULL
#define NONE_STRING  "__NONE-*-*-STRING__"

class _NoneType
{
 public:
   static double   None(double _)     { return NONE_DOUBLE;}
   static float    None(float _)      { return NONE_FLOAT; }
   static int      None(int _)        { return NONE_INT;   }
   static uint     None(uint _)       { return NONE_UINT;  }
   static long     None(long _)       { return NONE_LONG;  }
   static ulong    None(ulong _)      { return NONE_ULONG; }
   static char     None(char _)       { return NONE_CHAR;  }
   static uchar    None(uchar _)      { return NONE_UCHAR; }
   static short    None(short _)      { return NONE_SHORT; }
   static ushort   None(ushort _)     { return NONE_USHORT;}
   static string   None(string _)     { return NONE_STRING;}
   static color    None(color _)      { return NONE_COLOR; }
   static datetime None(datetime _)   { return NONE_DATETIME;}
   template<typename T>
   static T        None(T _)          { return NONE_POINTER;}
   
   static bool    IsNone( const double   Value ) { return(Value == NONE_DOUBLE); }
   static bool    IsNone( const float    Value ) { return(Value == NONE_FLOAT); }
   static bool    IsNone( const int      Value ) { return(Value == NONE_INT); }
   static bool    IsNone( const uint     Value ) { return(Value == NONE_UINT); }
   static bool    IsNone( const long     Value ) { return(Value == NONE_LONG); }
   static bool    IsNone( const ulong    Value ) { return(Value == NONE_ULONG); }
   static bool    IsNone( const char     Value ) { return(Value == NONE_CHAR); }
   static bool    IsNone( const uchar    Value ) { return(Value == NONE_UCHAR); }
   static bool    IsNone( const short    Value ) { return(Value == NONE_SHORT); }
   static bool    IsNone( const ushort   Value ) { return(Value == NONE_USHORT); }
   static bool    IsNone( const color    Value ) { return(Value == NONE_COLOR); }
   static bool    IsNone( const datetime Value ) { return(Value == NONE_DATETIME); }
   static bool    IsNone( const string   Value ) { return(Value == NONE_STRING); }
   template<typename T>
   static bool    IsNone( const T         Value ) { return(Value == NONE_POINTER);}
   
   
};

#define NONE(T)  _NoneType::None((T)NULL)
#define IS_NONE(VALUE)  _NoneType::IsNone(VALUE)


   double num = NONE(double);
   Print(IS_NONE(num));                 //true
   Print(IS_NONE(NONE(CObject*)));      //true
 
In the case of using IsNone the defines become redundant - which I think it's much better because it enforces to use only the functions alone

#define NONE_DOUBLE  DBL_MAX
#define NONE_FLOAT   FLT_MAX
#define NONE_INT     INT_MAX
#define NONE_UINT    UINT_MAX
#define NONE_LONG    LONG_MAX
#define NONE_ULONG   ULONG_MAX
#define NONE_CHAR    CHAR_MAX
#define NONE_UCHAR   UCHAR_MAX
#define NONE_SHORT   SHORT_MAX
#define NONE_USHORT  USHORT_MAX
#define NONE_COLOR   clrNONE
#define NONE_DATETIME -1
#define NONE_POINTER NULL
#define NONE_STRING  "__NONE-*-*-STRING__"
 
Amir Yacoby:
In the case of using IsNone the defines become redundant - which I think it's much better because it enforces to use only the functions alone

#define NONE_DOUBLE  DBL_MAX
#define NONE_FLOAT   FLT_MAX
#define NONE_INT     INT_MAX
#define NONE_UINT    UINT_MAX
#define NONE_LONG    LONG_MAX
#define NONE_ULONG   ULONG_MAX
#define NONE_CHAR    CHAR_MAX
#define NONE_UCHAR   UCHAR_MAX
#define NONE_SHORT   SHORT_MAX
#define NONE_USHORT  USHORT_MAX
#define NONE_COLOR   clrNONE
#define NONE_DATETIME -1
#define NONE_POINTER NULL
#define NONE_STRING  "__NONE-*-*-STRING__"

Yes, the only time you need to use the NONE/IS_NONE macros is when working with templates. Otherwise it is more efficient to use constants and expressions. 

static double low_bid = NONE_DOUBLE;
if(num == NONE_DOUBLE || Bid < low_bid)
   low_bid = Bid;
 
nicholi shen:

Yes, the only time you need to use the NONE/IS_NONE macros is when working with templates. Otherwise it is more efficient to use constants and expressions. 

That's correct.
Btw, there's another interesting use for this lib that crossed my mind. 
You can pass to functions/methods any combination of parameters with default values (not restricted to the end of parameters list)
bool Func(int parm1=NONE_INT,double parm2=5.1,long parm3=NONE_LONG,string parm4=NONE_STRING)
  {
   string str;
   if(!ISNONE(parm1)) str+=" parm1="+(string)parm1;
   if(!ISNONE(parm2)) str+=" parm2="+(string)parm2;
   if(!ISNONE(parm3)) str+=" parm3="+(string)parm3;
   if(!ISNONE(parm4)) str+=" parm4="+(string)parm4;
   Print(str);
   return true;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   Func(5);                                           // pass only 1st
   Func();                                            // pass only 2nd
   Func(NONE_INT,5.2,NONE_LONG,"strval");             // pass 2nd & 4th
  }

*-in that case it is better to give the default positive value in the function method itself (for parm2=5.1):

bool Func(int parm1=NONE_INT,double parm2=NONE_DOUBLE,long parm3=NONE_LONG,string parm4=NONE_STRING)
{
 if(IsNone(parm2)) parm2=5.1; // the default
..
}

Which allows to call without the caller knowing the actual default value of the 2nd parameter.


Reason: