Questions on OOP in MQL5 - page 88

 
Igor Makanu:
same values, the speed of the test "floats" for some reason, but passing parameters in methods by reference is still more efficient

Then there's this option:

class E
{
   double f1( double a, double b )  { return(a + 1.0/(1.0+(double)rand())); }
   double f2( double a, double b )  { return(b + 1.0/(1.0+(double)rand())); }
   double f3( double a, double b )  { return(a/b + 1.0/(1.0+(double)rand())); }
   
public:
   double calc( const MqlTick& tick )
   {
      return f1( tick.ask, tick.bid ) + f2( tick.ask, tick.bid ) + f3( tick.ask, tick.bid );
   }
};
 
Koldun Zloy:

Then there is also this option:

2020.07.26 10:10:52.254 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46141

2020.07.26 10:11:30.261 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38000

2020.07.26 10:12:08.258 class_global (EURUSD,H1) class C : : loops = 10000000000 ms=38000

2020.07.26 10:12:46.254 class_global (EURUSD,H1) class D : : : loops = 10000000000 ms=38000

2020.07.26 10:13:24.279 class_global (EURUSD,H1) class E : : loops = 10000000000 ms=38031

2020.07.26 10:14:10.484 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46203

2020.07.26 10:14:48.570 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38078

2020.07.26 10:15:26.737 class_global (EURUSD,H1) class C : : loops = 10000000000 ms=38172

2020.07.26 10:16:04.734 class_global (EURUSD,H1) class D : : : loops = 10000000000 ms=38000

2020.07.26 10:16:42.739 class_global (EURUSD,H1) class E : : loops = 10000000000 ms=38000

2020.07.26 10:17:28.886 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46141

2020.07.26 10:18:06.894 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38015

2020.07.26 10:18:44.888 class_global (EURUSD,H1) class C : : loops = 10000000000 ms=38000

2020.07.26 10:19:22.948 class_global (EURUSD,H1) class D : : : loops = 10000000000 ms=38047

2020.07.26 10:20:00.983 class_global (EURUSD,H1) class E : : loops = 10000000000 ms=38047

strange, but no difference

UPD: if i'm not mistaken, i looked for a mistake in MT4 years ago - i passed arguments to a function NOT by reference and then i changed (made a mistake) one of the function arguments in the function body. i could change an argument passed by reference, maybe in the E variant the compiler passed all arguments by reference too.

 
Igor Makanu:
strange, but there's no difference.

There's nothing strange about it. double is 8 bytes, the reference is also 8 bytes. But the reference still has to get the 8 bytes of the number.

 
Koldun Zloy:

There's nothing strange about it. double is 8 bytes, the reference is also 8 bytes. But the link still has to get 8 bytes of a number.

That makes sense, and the numbers add up to 8 there and 8 back ))

but the bus isn't 8 bit in a processor? should read 8 bytes = 64 bits per clock cycle ?

 
Igor Makanu:

that makes sense, and the numbers add up to 8 there and 8 back ))

But the bus isn't 8 bits in a processor, is it supposed to read 8 bytes = 64 bits per clock cycle ?

It's not that simple there. The speed depends both on what memory the object is in and other reasons.

In a real program, the result may be very much different from that of a simple test.

Usually classes and structures are passed by reference.

Simple types are passed by reference only if some value is returned by it.

 

I was surprised to find out that structure fields can be accessed even if this structure is returned as a function result

this code works correctly (we fill the structure in the function, then copy the result of the function into a byte array)

struct UcharArray
{
   uchar             byte[];
};
//+------------------------------------------------------------------+
UcharArray f()
{
   UcharArray result;
   for(uchar i = 0; i < 10; i++)
   {
      uchar tmp[1];
      tmp[0] = i;
      ArrayCopy(result.byte, tmp, ArraySize(result.byte));
   }
   return result;
}
//+------------------------------------------------------------------+
void OnStart()
{
   uchar arr[];
   for(int i = 0; i < 3; i++)
   {
      ArrayCopy(arr, f().byte, ArraySize(arr));
   }
   
   ArrayPrint(arr); // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

}
//+------------------------------------------------------------------+

it is convenient to use such access to the structure field, .... where can there be pitfalls - bugs/errors ?

 
Igor Makanu:

I was surprised to find out that structure fields can be accessed even if this structure is returned as a function result

this code works correctly (we fill the structure in the function, then copy the result of the function into a byte array)

it is convenient to use such access to the structure field, .... where can there be pitfalls/bugs/errors ?

This kind of thing)) there are no bugs.

 ArrayCopy(arr, (f()).byte, ArraySize(arr))

So more correctly it's from the opera (.)(.)

I also don't understand what copying into byte array has to do with it. It's just about accessing data from the returned structure
 
Alexandr Andreev:
This is just accessing data of the returned structure

Yes, but it's confusing that I'm accessing the byte field without an intermediate variable, directly to the result of the f() function

that's why I'm waiting for a catch

f().byte
 
Igor Makanu:

Yes, but it's confusing that I'm accessing the byte field without an intermediate variable, directly to the result of the f() function

that's why I'm waiting for a catch

it's been stable for a few years now.

 
Alexandr Andreev:

has been stable for a few years now.

OK, thank you!