Características da linguagem mql5, subtilezas e técnicas - página 110

 

Fórum sobre comércio, sistemas automatizados de comércio e testes de estratégia comercial

Insectos, insectos, perguntas

fxsaber, 2018.12.01 11:15

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

FileReadArray(handle, Str);

Um ficheiro de 40Mb de 1 milhão de linhas leva 18 segundos para ser lido.


O mesmo resultado de saída, mas feito de forma diferente

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

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

Já está feito em 0,5 segundos.


 
Um truque 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>();
}
 

Uma simples contrapartida ao auto_ptr (considerado obsoleto). Nota: não muito análogo, com
...


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

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

pavlick_

Uma linha no início deve ser adicionada a operator=:

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

Embora provavelmente valha a pena limitar-se a algo como isto (não se pode copiar de todo):

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;
   }
};
Porque é que fiz uma cópia para o auto_ptr? Devido à curvatura do µl - para copiar um objecto de pilha para o CArrayObj é necessário criar um monte de objectos, chamando ao construtor um monte de vezes. Mas acho que não vale a pena. A este respeito, retirarei o primeiro posto.
 
pavlick_:

Porque é que fiz uma cópia para o auto_ptr? Devido à curvatura μl - para copiar um objecto de pilha para o CArrayObj é necessário criar um monte de objectos, chamando ao construtor um monte de vezes.

E porquê "a curvatura de μl"?

 
Alexey Navoykov:

E porquê a "tortuosidade do µl"?

A tarefa trivial de adicionar uma cópia de um objecto de pilha a um array é adicionar um construtor por defeito, do qual não precisava em primeiro 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;
}

Não é fatal, sim, pode fazer init() no Q, o que vai suavizar um pouco o problema, mas continua a ser nojento. E quando se copia auto_ptr na mão, tudo acontece em duas linhas, mas o jogo não vale a pena o esforço. Talvez demasiado picuinhas, perfeccionismo.

 
pavlick_:

A tarefa trivial de adicionar uma cópia de um objecto de pilha a um array acaba por ser esta + eu preciso de prescrever um construtor por defeito, do qual eu não precisava de todo:

Não é fatal, sim, pode fazer init() no Q, o que vai suavizar um pouco o problema, mas continua a ser nojento. E quando se copia auto_ptr na mão, tudo acontece em duas linhas, mas o jogo não vale o esforço. Talvez demasiado picuinhas, perfeccionismo.

Mas é exactamente o mesmo em C++ também, por isso não é realmente claro porque é que o mcl torto.

E no seu caso é mais fácil especificar o construtor de cópias, e adicionar elementos com uma linha:

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

A tarefa trivial de adicionar uma cópia de um objecto de pilha a um array acaba por ser esta + eu preciso de escrever um construtor por defeito, do qual não precisava de forma alguma:

Não é fatal, sim, pode fazer init() no Q, o que vai suavizar um pouco o problema, mas continua a ser nojento. E quando se tem cópia auto_ptr, tudo acontece em duas linhas, mas o jogo não vale o esforço. Talvez demasiado picuinhas, perfeccionismo.

É assim que tudo acontece de qualquer maneira - está apenas escondido atrás do seu auto_ptr...

Não vejo aqui nenhum problema especial.

Como um temporizador antigo endurecido, não gosto muito da abordagem C# onde a memória é apagada automaticamente. Na minha opinião, foi a pessoa que solicitou a eliminação de objectos, e não alguns "coleccionadores de lixo" que deveriam ser responsáveis por ela.

 
Alexey Navoykov:

Mas é exactamente o mesmo em C++, por isso não é muito claro porque é que o mcl está torto.

E no seu caso é mais fácil especificar um construtor de cópias, e adicionar elementos numa só linha:

Como é que é o mesmo? Há lá um construtor de cópias automaticamente e todas as manipulações terão um olhar:

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

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

E no seu caso é mais fácil definir o construtor de cópias e adicionar elementos com uma linha

Claro que é uma classe de brinquedos, por exemplo, na realidade são também alguns dados, provavelmente muitos, não é uma opção para escrever um construtor de cópias. Embrulhado nos locais certos em invólucros e sem necessidade de um construtor à medida.

Por isso, tudo acontece de qualquer maneira - está apenas escondido atrás do seu auto_ptr...

Não vejo aqui qualquer problema em particular.

Como um temporizador antigo endurecido, não gosto da abordagem C# onde a memória é apagada automaticamente. Na minha opinião, a pessoa que solicitou a eliminação de objectos deve ser responsável por ela, e não algum coleccionador de lixo.

Em µl, pode prescindir de apontadores inteligentes. Colector de lixo != apontadores inteligentes, não se pode passar sem eles, pelo menos por causa de excepções. Eu próprio não gosto de coleccionadores de lixo.