Caractéristiques du langage mql5, subtilités et techniques - page 110

 

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

Bugs, bugs, questions

fxsaber, 2018.12.01 11:15

Conception du super-frein
string Str[];
const int handle = FileOpen(FileName, FILE_READ | FILE_ANSI | FILE_TXT);  

FileReadArray(handle, Str);

Un fichier de 40 Mo contenant 1 million de lignes prend 18 secondes à lire.


Le même résultat de sortie, mais fait différemment

  uchar Bytes[];
  const int handle = FileOpen(FileName, FILE_READ | FILE_BIN);
  
  FileReadArray(handle, Bytes);

  string Str[];
  StringSplit(CharArrayToString(Bytes), '\n', Str);

est déjà fait en 0,5 seconde.


 
Une astuce artificielle pour compiler
#define  MACROS(A, B) A / B + !(A / B) // (A >= B) ? A / B : 1

template <typename T1, typename T2>
union UNION
{
  T1 a;
//  T2 b[sizeof(T1) / sizeof(T2)];      // '[' - invalid index value
  T2 b[MACROS(sizeof(T1), sizeof(T2))]; // OK
};

template <typename T1, typename T2>
void f()
{
  if (sizeof(T1) >= sizeof(T2))
    UNION<T1, T2> Union;
  else
    UNION<T2, T1> Union;  
}

void OnStart()
{
  f<int, char>();
}
 

Une contrepartie simple à auto_ptr (considéré comme obsolète). Note : pas tout à fait analogue, avec
...


https://habr.com/post/140222/

Smart pointers для начинающих
Smart pointers для начинающих
  • habr.com
Эта небольшая статья в первую очередь предназначена для начинающих C++ программистов, которые либо слышали об умных указателях, но боялись их применять, либо они устали следить за new-delete. UPD: Статья писалась, когда C++11 еще не был так популярен. Итак, программисты С++ знают, что память нужно освобождать. Желательно всегда. И они знают...
 

pavlick_

Une ligne au début devrait être ajoutée à operator= :

if (p==other.p) return &this;
 

Bien que cela vaille probablement la peine de se limiter à quelque chose comme ça (vous ne pouvez pas copier du tout) :

template <typename T_>
class unique_ptr{
   T_ *p;
public:
   unique_ptr(void *ptr=NULL): p(ptr)           {}
   ~unique_ptr()                                {reset();}
   unique_ptr *operator=(T_ *p_)                {reset(); p = p_; return &this;}
   // releases ownership of the managed object
   T_ *release()                                   {T_ *r = p; p = NULL; return r;}
   // destroys the managed object 
   void reset()                                    {if(p) delete p; p=NULL;}
   // returns a pointer to the managed object 
   T_ *get()                                       {return p;}
   unique_ptr(const unique_ptr<T_> &other);
   void operator=(const unique_ptr<T_> &other);
   void swap(unique_ptr<T_> &other){
      T_ *buf = p;
      p = other.p;
      other.p = buf;
   }
};
Pourquoi ai-je fait la copie pour auto_ptr ? En raison de la courbure de µl - pour copier un objet de la pile vers CArrayObj, vous devez créer un tas d'objets en appelant le constructeur un tas de fois. Mais je ne pense pas que ça en vaille la peine. À cet égard, je vais retirer le premier message.
 
pavlick_:

Pourquoi ai-je fait la copie pour auto_ptr ? En raison de la courbure de µl - pour copier un objet de la pile vers CArrayObj, vous devez créer un tas d'objets en appelant le constructeur un tas de fois.

Et pourquoi "la courbure de μl" ?

 
Alexey Navoykov:

Et pourquoi le "crochetage du µl" ?

La tâche triviale d'ajouter une copie d'un objet de pile à un tableau est d'ajouter un constructeur par défaut, dont je n'avais pas besoin en premier lieu :

class Q : public CObject {
public:
   Q() {}
   Q(int i) {}
};

void OnStart()
{
   CArrayObj ar;
   Q q(3);
   
   Q *new_el = new Q;
   new_el = q;
   ar.Add(new_el);
   Q new_el2(5);
   q = new_el2;
}

Ce n'est pas fatal, oui, vous pouvez faire init() à Q, ce qui atténue un peu le problème, mais quand même - c'est dégoûtant. Et en copiant auto_ptr à la main, tout se passe en deux lignes, mais le jeu n'en vaut pas la chandelle. Peut-être trop pointilleux, perfectionnisme.

 
pavlick_:

La tâche triviale d'ajouter une copie d'un objet de pile à un tableau s'avère être la suivante + je dois prescrire un constructeur par défaut, dont je n'avais pas du tout besoin :

Ce n'est pas fatal, oui, vous pouvez faire init() à Q, ce qui lissera un peu le problème, mais c'est quand même dégoûtant. Et quand on copie auto_ptr à la main, tout se passe en deux lignes, mais le jeu n'en vaut pas la chandelle. Peut-être trop pointilleux, perfectionnisme.

Mais c'est exactement la même chose en C++ aussi, donc on ne sait pas vraiment pourquoi la mcl tordue.

Et dans votre cas, il est plus facile de spécifier le constructeur de copie, et d'ajouter des éléments avec une seule ligne :

ar.Add(new Q(q));
 
pavlick_:

La tâche triviale d'ajouter une copie d'un objet de la pile à un tableau s'avère être la suivante + je dois écrire un constructeur par défaut, ce dont je n'avais pas du tout besoin :

Pas fatal, oui, vous pouvez faire init() à Q, ce qui atténuera un peu le problème, mais c'est quand même dégoûtant. Et quand on a copié auto_ptr, tout se passe en deux lignes, mais le jeu n'en vaut pas la chandelle. Peut-être trop pointilleux, perfectionnisme.

C'est comme ça que ça se passe de toute façon - c'est juste caché derrière votre auto_ptr...

Je ne vois pas de problèmes particuliers ici.

En tant que vieux routier endurci, je n'aime vraiment pas l'approche du C# où la mémoire est supprimée automatiquement. À mon sens, c'est la personne qui a demandé la suppression des objets, et non des "collecteurs de déchets", qui devrait en être responsable.

 
Alexey Navoykov:

Mais c'est exactement la même chose en C++, donc on ne voit pas très bien pourquoi la mcl est tordue.

Et dans votre cas, il est plus facile de spécifier un constructeur de copie, et d'ajouter des éléments en une seule ligne :

En quoi est-ce la même chose ? Il y a un constructeur de copie automatiquement et toutes les manipulations auront un regard :

class Q : public CObject {
public:
   Q(int i) {}
};

void OnStart()
{
   CArrayObj ar;
   Q q(3);
   
   ar.Add(new(q));
   q = Q(5);
}

Dans votre cas, il est plus facile de définir un constructeur de copie et d'ajouter des éléments en une seule ligne.

Bien sûr, c'est une classe jouet par exemple, en réalité c'est aussi des données, probablement beaucoup, ce n'est pas du tout une option pour écrire un constructeur de copie. Enveloppé aux bons endroits dans des wrappers et pas besoin d'un constructeur personnalisé.

Donc tout se passe de toute façon - c'est juste caché derrière votre auto_ptr...

Je ne vois pas de problème particulier ici.

En tant que vieux routier endurci, je n'aime pas l'approche du C# où la mémoire est supprimée automatiquement. À mon sens, c'est la personne qui a demandé la suppression des objets qui devrait en être responsable, et non un quelconque collecteur de déchets.

En µl, on peut se passer des pointeurs intelligents. Collecteur de déchets != pointeurs intelligents, vous ne pouvez pas vous en passer, au moins à cause des exceptions. Je n'aime pas le ramasseur d'ordures moi-même.