Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 110

 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Bug, bug, domande

fxsaber, 2018.12.01 11:15

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

FileReadArray(handle, Str);

Un file di 40Mb di 1 milione di linee richiede 18 secondi per essere letto.


Lo stesso risultato di uscita, ma fatto in modo diverso

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

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

È già fatto in 0,5 secondi.


 
Un trucco artificiale per compilare
#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>();
}
 

Una semplice controparte di auto_ptr (considerato obsoleto). Nota: non del tutto analogo, con
...


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

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

pavlick_

In operator= dovete aggiungere una linea all'inizio:

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

Anche se probabilmente vale la pena limitarsi a qualcosa del genere (non si può copiare affatto):

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;
   }
};
Perché ho fatto la copia per auto_ptr? A causa della curvatura di µl - per copiare l'oggetto stack in CArrayObj dovete creare un mucchio di oggetti chiamando il costruttore un mucchio di volte. Ma non credo che ne valga la pena. A questo proposito, toglierò il primo post.
 
pavlick_:

Perché ho fatto la copia per auto_ptr? A causa della curvatura di µl - per copiare un oggetto stack in CArrayObj dovete creare un mucchio di oggetti chiamando il costruttore un mucchio di volte.

E perché "la curvatura di μl"?

 
Alexey Navoykov:

E perché la "stortura del µl"?

Il compito banale di aggiungere una copia di un oggetto stack ad un array è quello di aggiungere un costruttore di default, di cui non avevo bisogno in primo luogo:

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;
}

Non è fatale, sì, si può fare init() a Q, che appianerà un po' il problema, ma comunque - è disgustoso. E quando si copia auto_ptr a mano, tutto avviene in due righe, ma il gioco non vale la pena. Forse troppo esigente, perfezionismo.

 
pavlick_:

Il compito banale di aggiungere una copia di un oggetto stack a un array si rivela essere questo + ho bisogno di prescrivere un costruttore di default, di cui non avevo affatto bisogno:

Non è fatale, sì, potete fare init() a Q, che appianerà un po' il problema, ma è ancora disgustoso. E quando si copia auto_ptr a mano, tutto avviene in due righe, ma il gioco non vale la pena. Forse troppo esigente, perfezionismo.

Ma è esattamente la stessa cosa anche in C++, quindi non è molto chiaro perché il mcl storto.

E nel tuo caso è più facile specificare il costruttore di copia e aggiungere elementi con una sola linea:

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

Il compito banale di aggiungere una copia di un oggetto stack a un array si rivela essere questo + ho bisogno di scrivere un costruttore di default, di cui non avevo affatto bisogno:

Non fatale, sì, potete fare init() a Q, che appianerà un po' il problema, ma è ancora disgustoso. E quando si ha la copia di auto_ptr, tutto avviene in due righe, ma il gioco non vale la pena. Forse troppo esigente, perfezionismo.

Questo è il modo in cui tutto avviene comunque - è solo nascosto dietro il tuo auto_ptr...

Non vedo nessun problema particolare qui.

Come vecchio timer incallito, non mi piace molto l'approccio C# in cui la memoria viene cancellata automaticamente. A mio parere, è la persona che ha richiesto la cancellazione degli oggetti, non alcuni "raccoglitori di rifiuti" che dovrebbe essere responsabile.

 
Alexey Navoykov:

Ma è esattamente lo stesso in C++, quindi non è molto chiaro perché l'mcl sia storto.

E nel tuo caso è più facile specificare un costruttore di copia, e aggiungere elementi in una sola linea:

In che modo è la stessa cosa? C'è un costruttore di copie lì automaticamente e tutte le manipolazioni avranno un aspetto:

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

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

E nel tuo caso è più facile impostare il costruttore di copia e aggiungere elementi con una sola linea

Certo, è una classe giocattolo per esempio, in realtà sono anche dei dati, probabilmente molti, non è assolutamente possibile scrivere un costruttore di copia. Avvolti i posti giusti nei wrapper e nessun bisogno di un costruttore personalizzato.

Quindi succede tutto comunque - è solo nascosto dietro il tuo auto_ptr...

Non vedo alcun problema particolare qui.

Come vecchio tempista incallito, non mi piace l'approccio C# in cui la memoria viene cancellata automaticamente. A mio parere, la persona che ha richiesto la cancellazione degli oggetti dovrebbe esserne responsabile, non un raccoglitore di rifiuti.

In µl, si può fare a meno dei puntatori intelligenti. Raccoglitore di spazzatura != puntatori intelligenti, non se ne può fare a meno almeno per le eccezioni. Io stesso non amo i raccoglitori di rifiuti.