Generic Class Library - bugs, description, questions, usage and suggestions

 

As of December 6, 2017, the standard MetaTrader 5 delivery set includes the so-called Generic classes, which implement efficient algorithms for data storage and extraction. This branch was created to describe these classes, examples of working with them, as well as for suggestions on how to improve their work.

What is Generic? Generic is a special template classes that can store custom data types. In this case, the type is identified at the time of compilation, which achieves high performance.

Why Generic? Typically, novice programmers are familiar with only one type of collection: an array. But there are many tasks where working with arrays is ineffective. Imagine that we have an array consisting of a million unique identifiers, for example, a thousand orders. How can we check whether in this thousand of orders, there is one order with number N? If we use one of the generic classes, this task can be accomplished almost immediately, in a constant amount of time, which does not depend on the number of elements to be searched among. There are other problems where the correct algorithm from the generic collection can be faster than the algorithm invented by the programmer.

Generic algorithms. Below is a table of generic classes, with a brief description of what they do:

ClassClass Description
CArrayList .An array, with automatic size repartitioning. Allows you to take advantage of an array without the need for controlling the exit from it.
CHashMapA key-value set. Allows you to efficiently insert, retrieve, and search elements by their key. The key must be unique. For example, CHashMap can instantly find an order with a specified number, where the number is used as a key.
СHashSetA set of unique elements. Allows you to do the same as CHashMap, but does not require a specified key. Elements stored in this collection must not be repeated. It also allows you to instantly search, retrieve, and add items.
CLinkedListA double linked list. Makes it easy to insert and remove items. However, it takes a time linearly dependent on the number of items in it to find the right one.
CQueueHeap. It organizes a FIFO-type queue
CStackStack. Organizes queue of LIFO type
CRedBlackTreeRedBlackTree. Allows fast (in logarithmic time) inserting, retrieving and finding elements. Unlike CHashMap and CHashSet, it allows to efficiently implement additional relational algorithms like more than, less than, between, etc.
CSortedMapSorted set by key. Stores key-values. In this case the key is sorted.
CSortedSetA sorted set by value. Stores an ordered set of values.

We will go on later and look at the implementation features of these classes.

 
Vasiliy Sokolov:

Imagine that we have an array of a million unique identifiers, such as a thousand orders. How can we check if in this thousand of orders, there is one order with number N? If we use one of the generic classes, this task can be accomplished almost instantly, in a constant amount of time, which doesn't depend on the number of elements searched for.

Not familiar with the topic at all. But the highlighted sounds illogical.

 

Unfortunately, the library has just been released and is still raw. I've already found the first error in it (I'll highlight errors with a highlighter):

Error in CSortedSet:

//+------------------------------------------------------------------+
//| Class CSortedSet<T>.                                             |
//| Usage: Represents a collection of objects that is maintained in  |
//|        sorted order.                                             |
//+------------------------------------------------------------------+
template<typename T>
class CSortedSet: public ISet<T>
  {
   ...
   bool              TryGetMin(T &min)    { return(m_tree.TryGetMin(min)); }
   bool              TryGetMax(T &max)    { return(m_tree.TryGetMin(max)); }
   ...
  }

TryGetMax method returns not the maximum but the minimum element, as well as TryGetMin

 
fxsaber:

... But the highlighted sounds illogical.

Why is that?

 
Vasiliy Sokolov:

Why is that?

Make hashes, sort them in ascending order. But there will be a search anyway.

 
fxsaber:

Not familiar with the topic at all. But the highlighted sounds illogical.

average time O(1) worst O(n) and performance is highly dependent on hash.
 
fxsaber:

Making hashes...

Let's define the terminology. Nothing is instantaneous. Every operation takes time. When I say instantaneous, I'm simplifying it so that novice programmers understand me. Strictly speaking, there are several classes of complexity, the main ones we'll deal with are the following:

  • Constant complexity cO(1).
  • Logarithmic: cO(log n).
  • Linear: cO (n).
  • Algorithms that require non linear execution time.

I deliberately introduced the c sign - as a certain constant that occurs when calculating the hash, and other technical manipulations. But in this case, the discussion about optimization of constantc is off topic of this thread. We are interested here only in generic classes and their application in practice.

 
fxsaber:

Make hashes, sort them in ascending order. But the search will be in any case.

Combinator:
Average time O(1) worst O(n) and the perfomance is highly dependent on the hash.

+

p.s. To illustrate, here's an example where this same perfomance will drop to O(n) if you don't work with CHashMap correctly.

 

I suggest to simplify the names - make them more logical. For example, is CArrayList an Array or List in mql5 the implementation of both?

This all leads to questions and confusion. IMHO, we should use stl instead of C# or Java. Or remove C in front of it then, let it just be ArrayList.


If you make normal names:

- readability will improve many times over.

- you will have your own specific mql5 style.

- newbies will be able to immediately navigate the code (because stl is included in the standard)

 
Vasiliy Sokolov:

...

If you can give examples, for example, about searching among thousands of deals.
Reason: