Características del lenguaje mql5, sutilezas y técnicas - página 110

 

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Bichos, errores, preguntas

fxsaber, 2018.12.01 11:15

Diseño de superfreno
string Str[];
const int handle = FileOpen(FileName, FILE_READ | FILE_ANSI | FILE_TXT);  

FileReadArray(handle, Str);

Un archivo de 40Mb de 1 millón de líneas tarda 18 segundos en leerse.


El mismo resultado de salida, pero hecho de manera diferente

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

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

Ya está hecho en 0,5 segundos.


 
Un truco artificial para compilar
#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 contraparte simple de auto_ptr (considerada obsoleta). Nota: no es del todo análogo, con
...


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

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

pavlick_

Hay que añadir una línea al principio a operator=:

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

Aunque probablemente valga la pena limitarse a algo así (no se puede copiar en absoluto):

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;
   }
};
¿Por qué hice copias para auto_ptr? Debido a la curvatura de µl - para copiar el objeto pila a CArrayObj hay que crear un montón de objetos llamando al constructor un montón de veces. Pero no creo que valga la pena. En este sentido, voy a retirar el primer post.
 
pavlick_:

¿Por qué hice copias para auto_ptr? Debido a la curvatura de µl - para copiar un objeto de pila a CArrayObj tienes que crear un montón de objetos llamando al constructor un montón de veces.

¿Y por qué "la curvatura de μl"?

 
Alexey Navoykov:

¿Y por qué la "torcedura de la µl"?

La tarea trivial de añadir una copia de un objeto de pila a un array es añadir un constructor por defecto, que no necesitaba en primer lugar:

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

No es fatal, sí, puedes hacer init() en Q, lo que suavizará un poco el problema, pero aun así es un asco. Y al copiar auto_ptr a mano, todo pasa en dos líneas, pero el juego no vale la pena. Quizás demasiado exigente, perfeccionista.

 
pavlick_:

La tarea trivial de añadir una copia de un objeto de la pila a un array resulta ser esto + tengo que prescribir un constructor por defecto, que no necesitaba en absoluto:

No es fatal, sí, puedes hacer init() en Q, lo que suavizará un poco el problema, pero sigue siendo desagradable. Y al copiar auto_ptr a mano, todo pasa en dos líneas, pero el juego no vale la pena. Quizás demasiado exigente, perfeccionista.

Pero es exactamente igual en C++ también, así que no está muy claro por qué el mcl torcido.

Y en tu caso es más fácil especificar el constructor de copia, y añadir elementos con una sola línea:

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

La tarea trivial de añadir una copia de un objeto de la pila a un array resulta ser esto + tengo que escribir un constructor por defecto, que no necesitaba en absoluto:

No es fatal, sí, puedes hacer init() en Q, lo que suavizará un poco el problema, pero sigue siendo desagradable. Y cuando se ha copiado auto_ptr, todo pasa en dos líneas, pero el juego no merece la pena. Quizás demasiado exigente, perfeccionista.

Así es como todo sucede de todos modos - sólo se oculta detrás de su auto_ptr...

No veo ningún problema especial aquí.

Como veterano empedernido, me desagrada mucho el enfoque de C# en el que la memoria se borra automáticamente. En mi opinión, es la persona que ha solicitado la eliminación de objetos, y no unos "recolectores de basura", quien debería ser responsable de ello.

 
Alexey Navoykov:

Pero es exactamente lo mismo en C++, así que no está muy claro por qué el mcl está torcido.

Y en tu caso es más fácil especificar un constructor de copia, y añadir elementos en una sola línea:

¿Cómo es lo mismo? Hay un constructor de copias allí automáticamente y todas las manipulaciones tendrán una mirada:

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

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

Y en tu caso es más fácil establecer el constructor de copia y añadir elementos con una sola línea

Por supuesto, es una clase de juguete por ejemplo, en la realidad son algunos datos también, probablemente mucho, no es una opción para escribir un constructor de copia en absoluto. Envuelto en los lugares correctos en envolturas y sin necesidad de un constructor personalizado.

Así que todo sucede de todos modos - sólo se oculta detrás de su auto_ptr...

No veo ningún problema en particular.

Como veterano endurecido, no me gusta el enfoque de C# en el que la memoria se borra automáticamente. En mi opinión, la persona que solicitó la eliminación de objetos debería ser responsable de ello, no un recolector de basura.

En µl, se puede prescindir de los punteros inteligentes. Recolector de basura != punteros inteligentes, no se puede prescindir de ellos al menos por las excepciones. A mí tampoco me gusta el recolector de basura.