Classes, Objects and Memory Management question

 

Hey all!

I'm using some libraries from the standard library in MQL5. Yet, I have some questions about some things related to performance. I'm mainly playing with CPositionInfo at the moment, my questions are the following:

1- Is there any performance/runtime advantage by using the class to create an object and retrieve the position's information vs using the built in functions? (might be a rather silly question but I'm not that related to OOP yet)

2- Given the following code: (non tested, meant to be just a dummy for the example)

void CClass::SomeFunction()
{
        CPositionInfo position_info;
      
        for (int i = 0, positions_total = PositionsTotal(); i < positions_total; i++)
        {
                ulong ticket = PositionGetTicket(i);
         
                if (ticket > 0)
                {
                // Stuff related to retrieving the position's properties...
                }

                else
                {
                // Stuff related to error management...
                }
        }
}

During runtime, when the function execution finishes, thus, the position_info object going out of scope, is it recommended to call the object destructor at the very end of the function to free up the memory (since C# relies on .Net way of garbage collecting stuff in the memory and calling destructors when it considers appropriate instead of when they go out of scope, I'm assuming it's the same way with mql5), or just by going out of scope the way MQL5 works will take care of it?

Thanks in advance!

 
Fernando Jose Velasco Borea:

Hey all!

I'm using some libraries from the standard library in MQL5. Yet, I have some questions about some things related to performance. I'm mainly playing with CPositionInfo at the moment, my questions are the following:

1- Is there any performance/runtime advantage by using the class to create an object and retrieve the position's information vs using the built in functions? (might be a rather silly question but I'm not that related to OOP yet)

2- Given the following code: (non tested, meant to be just a dummy for the example)

During runtime, when the function execution finishes, thus, the position_info object going out of scope, is it recommended to call the object destructor at the very end of the function to free up the memory (since C# relies on .Net way of garbage collecting stuff in the memory and calling destructors when it considers appropriate instead of when they go out of scope, I'm assuming it's the same way with mql5), or just by going out of scope the way MQL5 works will take care of it?

Thanks in advance!

edit: The standard library is merely an abstraction for the built-in functions Try opening a position in MT5 without the library, then try using the library and tell me which one is easier.

As for performance, I've used the library for years, and performance has never been a problem. 

 

During runtime, when the function execution finishes, thus, the position_info object going out of scope, is it recommended to call the object destructor at the very end of the function to free up the memory (since C# relies on .Net way of garbage collecting stuff in the memory and calling destructors when it considers appropriate instead of when they go out of scope, I'm assuming it's the same way with mql5), or just by going out of scope the way MQL5 works will take care of it?

You should read about 'Lifetime and scope of variables'. There is so much to talk about here.

 
I will try to answer this in a broader context.

For algorithms there are (for simplicity) two types of data required.

The first type are parametric data, related to the "configuration" of the algorithm to be executed.
This includes data like the number of digits, symbol, state of code, and other arbitrary...

These informations usually do not change, or are changing throughout the execution path, but won't cumulate to an extend. (Like position management, money management, etc)


Then you have the data stream, like OHLC, tick volume, and any other data that changes and cumulates over time.

Both types are to be treated differently. Data of the first type will greatly benefit from preallocated memory and there is no sense in freeing this memory throughout the lifetime. Also variable memory areas like position data can be preallocated and kept available for fast access.

This will greatly enhance the execution speed of your code.

While the stream data needs different type of treatment. Here a "scope" on the stream is usually sufficient, when knowing the scope of data being relevant for the algorithm to compute it's output.

As you can see also within the whole API structure of MQL, this separation is implicitly already done for you. All you need to do is to integrate this into your Codedesign.

I hope this answers your question to your extend.
 
Dominik Egert #:
I will try to answer this in a broader context.

For algorithms there are (for simplicity) two types of data required.

The first type are parametric data, related to the "configuration" of the algorithm to be executed.
This includes data like the number of digits, symbol, state of code, and other arbitrary...

These informations usually do not change, or are changing throughout the execution path, but won't cumulate to an extend. (Like position management, money management, etc)


Then you have the data stream, like OHLC, tick volume, and any other data that changes and cumulates over time.

Both types are to be treated differently. Data of the first type will greatly benefit from preallocated memory and there is no sense in freeing this memory throughout the lifetime. Also variable memory areas like position data can be preallocated and kept available for fast access.

This will greatly enhance the execution speed of your code.

While the stream data needs different type of treatment. Here a "scope" on the stream is usually sufficient, when knowing the scope of data being relevant for the algorithm to compute it's output.

As you can see also within the whole API structure of MQL, this separation is implicitly already done for you. All you need to do is to integrate this into your Codedesign.

I hope this answers your question to your extend.
Thanks a lot!!

I just have one remaining question, when you say preallocate memoria to store the position data, do you mean to create a struct to store there the position info when reading it

 

Don't  worry about performance before writing the algorithm, first write the code focusing on it being readable, then,

if necessary where you are feeling the EA/Indicator to be slow, optimize it. MQL is fast enough most of the time.

 
You should read about 'Lifetime and scope of variables'. There is so much to talk about here.
Dominik Egert #:
While the stream data needs different type of treatment.  Here a "scope" on the stream is usually sufficient, when knowing the scope of data being relevant for the algorithm to compute it's output.    

As you can see also within the whole API structure of MQL, this separation is implicitly already done for you. All you need to do is to integrate this into your Codedesign.

and as an addition to this notes:

the scope - is your function or even less - any part of code between {...} -- when any object with automatic  storage duration (on stack) goes out of scope the Destructor of the class is destroying the object if it was allocated in stack (as it was not created dynamically with the keyword new)...and if it was created/allocated dynamically (onHeap), as pointer with keyword new - then it should be deleted explicitly with a keyword delete... in any case you can pass it as a parameter to other functions (aka other scopes) - & it will still be alive...

Lifetime starts with a creation of object and finishes as I have told either at the end of scope (if the object is automatically allocated in memory) or after using keyword delete (if the object is dynamic)...

If dynamic objects are put into the Container, then the Destructor of the Container can be responsible for their destroying [its about Ownership] -- e.g. ArrayObj & other Collections... container itself also can be created either automatically or dynamically - & will live in the same manner (either in the scope of creation or explicite delete needed)...

When you pass an object to another function - it usually is beeing copied - when passed ByValue - (in such a case - another equivalent object is created) & lives according to the same rules - in the scope (even pointer can be copied, but not the object it is pointing to - these are different pieces of memory - the pointer & the object pointed to)... or parameter to function is being passed by Reference ByRef -- you should understand this... but in MQL unlike C++ pointer is not pointing to the part of memory, but is just a handler ...

That is all you should understand initially  to make proper Codedesign -- you can search all additional information on objects, pointers, passing arguments  to functions in the MQL4/5 -language-reference pages ...

just hold in mind that the "scope" is a part between {...} - either function definition or even smaller piece of code among such brackets... if you are creating the  object automatically in the stack after opening-bracket - it will be destroyed after closing bracket... and dynamic objects (created on heap) - if not in any Container - live till you manually delete them - (am mentioning once again))... or dynamic objects can be destroyed with Container (if the Container has the Destructor, that delete dynamic objects in it, when the Container itself is being destroyed)

References: Modifier & and Keyword this - Data Types - Language Basics - MQL4 Reference
References: Modifier & and Keyword this - Data Types - Language Basics - MQL4 Reference
  • docs.mql4.com
References: Modifier & and Keyword this - Data Types - Language Basics - MQL4 Reference
 
JeeyCi #: Lifetime starts with a creation of object and finishes as I have told either at the end of scope (if the object is static) or after using keyword delete (if the object is dynamic)...

You keep using the word static, meaning permanent. Static variables, like globally declare variables, have a lifetime from script load to unload. Normal/regular variables go out of scope.

 
William Roeder #:

You keep using the word static, meaning permanent.

oh, yes - sorry... more precise - automatic storage duration (similarly to с++) - I wanted to say.. those that are allocated on the stack... corrected

 
Fernando Jose Velasco Borea #:    
I just have one remaining question, when you say preallocate memoria to store the position data, do you mean to create a struct to store there the position info when reading it  

structs can not be allocated dynamically, just class objects

Reason: