Особенности языка mql5, тонкости и приёмы работы - страница 110

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2018.12.01 11:15

Супер-тормозная конструкция
string Str[];
const int handle = FileOpen(FileName, FILE_READ | FILE_ANSI | FILE_TXT);  

FileReadArray(handle, Str);

Файл 40Мб из 1 миллиона строк считывает 18 секунд.


Тот же результат на выходе, но сделанный иначе

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

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

выполняется уже за 0.5 секунды.


 
Искусственный прием, чтобы компилировался
#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>();
}
 

Простенький аналог auto_ptr (считается устаревшим). Замечание: не совсем аналог, при
...


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

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

pavlick_

В operator= нужно добавить строчку в начале:

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

Хотя, наверное, стоит ограничиться лишь чем-то таким (нельзя копировать вообще):

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;
   }
};
Я для чего сделал копирование для auto_ptr? Из-за кривизны мкл - для копирования стекового объекта в CArrayObj нужно создать кучу объектов вызвав кучу раз конструктор. Но думаю, что оно того не стоит. В связи с этим, снесу первое сообщение.
 
pavlick_:

Я для чего сделал копирование для auto_ptr? Из-за кривизны мкл - для копирования стекового объекта в CArrayObj нужно создать кучу объектов вызвав кучу раз конструктор.

А почему "кривизна мкл"?

 
Alexey Navoykov:

А почему "кривизна мкл"?

Тривиальная задача - добавить копию стекового объекта в массив выливается в такое + нужно прописать дефолтный конструктор, который мне вообще не был нужен:

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

Не смертельно, да, можно сделать init() у Q, что чуть-чуть сгладит проблему, но всё равно - отвращение вызывает. А когда на руках копирующийся auto_ptr, то всё происходит в две строки, но игра свечь не стоит. Возможно слишком придираюсь, перфекционизм.

 
pavlick_:

Тривиальная задача - добавить копию стекового объекта в массив выливается в такое + нужно прописать дефолтный конструктор, который мне вообще не был нужен:

Не смертельно, да, можно сделать init() у Q, что чуть-чуть сгладит проблему, но всё равно - отвращение вызывает. А когда на руках копирующийся auto_ptr, то всё происходит в две строки, но игра свечь не стоит. Возможно слишком придираюсь, перфекционизм.

Но ведь и в С++ всё точно так же, поэтому не очень понятно, почему кривой мкл.

Да и в вашем случае проще задать конструктор копирования, и добавлять элементы одной строчкой:  

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

Тривиальная задача - добавить копию стекового объекта в массив выливается в такое + нужно прописать дефолтный конструктор, который мне вообще не был нужен:

Не смертельно, да, можно сделать init() у Q, что чуть-чуть сгладит проблему, но всё равно - отвращение вызывает. А когда на руках копирующийся auto_ptr, то всё происходит в две строки, но игра свечь не стоит. Возможно слишком придираюсь, перфекционизм.

Так ведь все равно все это происходит - просто оно скрыто за твоим auto_ptr...

Не вижу тут особых проблем.

Я, как закостенелый старпер - вобще очень не люблю подход C#, где память удаляется автоматически. По мне - за удаление объектов должен отвечать тот, кто их запросил, а вовсе не какие-то там "сборщики мусора".

 
Alexey Navoykov:

Но ведь и в С++ всё точно так же, поэтому не очень понятно, почему кривой мкл.

Да и в вашем случае проще задать конструктор копирования, и добавлять элементы одной строчкой:  

Как это так же? Там автоматом имеется копирующий конструктор и все манипуляции будут иметь вид:

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

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

Да и в вашем случае проще задать конструктор копирования, и добавлять элементы одной строчкой

Естсественно, что это игрушечный класс для примера, в реальности это и какие-то данные, возможно много, писать копирующий конструктор это вообще не вариант. Обвернули нужные места в обвёртки и ни к чему пользовательский конструктор.

Так ведь все равно все это происходит - просто оно скрыто за твоим auto_ptr...

Не вижу тут особых проблем.

Я, как закостенелый старпер - вобще очень не люблю подход C#, где память удаляется автоматически. По мне - за удаление объектов должен отвечать тот, кто их запросил, а вовсе не какие-то там "сборщики мусора".

В мкл можно и без умных указателей обойтись. Сборщик мусора != умные указатели, без них не обойтись хотя бы из-за исключений. Сборщик мусора я и сам не люблю. 

Причина обращения: