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

 
Maxim Kuznetsov #:

PPS/ ArrayPrint неудобен тем что печатает весь массив (они бывают эпичных размеров). Всё равно приходится переопределять, сокращая выхлоп

Там есть соответствующие входные.

 
Maxim Kuznetsov #:

INC_SORT_BY(array,field) - сортировать массив структур по заданному полю;

Короче уже вряд-ли возможно :-)

По теме производительности.

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

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

fxsaber, 2022.06.19 16:17

Alert: Bench_Stack = 0, 100 <= Time[Test9.mq5 129 in OnStart: SortOnField_Num::SORT::Sort(Array)] = 34574468 mcs.

Alert: Bench_Stack = 0, 100 <= Time[Test9.mq5 130 in OnStart: SortOnField_Num::SORT2::Sort(Array)] = 10586 mcs.
 

Я бы наоборот отказался от точки с запятой в конце вызова макроса, чтобы подчеркнуть, что это не функция.

 
fxsaber #:

Я бы наоборот отказался от точки с запятой в конце вызова макроса, чтобы подчеркнуть, что это не функция.

Тогда код становится хуже читаемым. Нарушается его восприятие. И ещё, при использовании цикла, в макросе можно использовать break.
 
Sergey Gridnev #:
Тогда код становится хуже читаемым. Нарушается его восприятие. И ещё, при использовании цикла, в макросе можно использовать break.

Интересно, отличается ли итоговый код компилятора с/без do-while, если не используется break.

 
Maxim Kuznetsov #:

пользователь-пользователь:

INC_SORT_BY(array,field) - сортировка массива структур по заданному полю;

Короче уже вряд ли возможно :-)

К сожалению, ваши макросы негибкие,

1. Для простых типов вы должны передавать аргумент функции сравнения.

2. Вы не можете сортировать структуру по нескольким полям, например, сортировать историю торговли по названию символа, а затем по дате входа.
Короче - не значит лучше, не знаю, кто это придумал 🤔.

 
Maxim Kuznetsov #:

пользователь-пользователь:

INC_SORT_BY(array,field) - сортировка массива структур по заданному полю;

Короче уже вряд ли возможно :-)

Я бы изменил ваши макросы в соответствии с этой лучшей реализацией:

/// СОРТИРОВКА

template <typename T>
void Swap(T &one,T &two)
{
   T tmp=two;
   two=one;
   one=tmp;
}

// Сортировка простых массивов int, string,... (в порядке возрастания)
#define   SORT(a) do { \
   for(int i=1; i < ArraySize(a); ++i) \
      for(int j=i; j>0 && (a[j]<a[j-1]); j--) { \
         Swap(a[j],a[j-1]); \
      } \
} while(0)

// Сортировка структур или простых массивов по заданному порядку
#define   SORT_BY(a, less) do { \
   for(int i=1; i < ArraySize(a); ++i) \
      for(int j=i; j>0 && less(a[j],a[j-1]); j--) { \
         Swap(a[j],a[j-1]); \
      } \
} while(0)

////////////////////////////
// ТЕСТ
struct rFoo {
   int key;
   double value;
};
bool AscByKey(rFoo &one,rFoo &two) {
   return one.key < two.key;
}
bool AscByValue(rFoo &one,rFoo &two) {
   return one.value < two.value;
}
bool Custom(rFoo &one,rFoo &two) { // возрастание по ключу, затем возрастание по значению
   if(one.key < two.key) return(true);
   if(one.key > two.key) return(false);
   // при равенстве по ключу
   if(one.value < two.value) return(true);
   if(one.value > two.value) return(false);
   // все поля равны
   return(false);
}
rFoo mass[] = {
   {11,0.18},
   {7,7.81},
   {7,1.25},
   {8,0.1},
   {100,5.11},
   {0,3.29},
   {0,1.43}
};


void OnStart()
{
   SORT_BY(mass,AscByKey);
   ArrayPrint(mass);

   SORT_BY(mass,AscByValue);
   ArrayPrint(mass);

   SORT_BY(mass,Custom);
   ArrayPrint(mass);
}
/*
 [ключ] [значение]
 [0] 0 3.29000
 [1] 0 1.43000
 [2] 7 7.81000
 [3] 7 1.25000
 [4] 8 0.10000
 [5] 11 0.18000
 [6] 100 5.11000
 [ключ] [значение]
 [0] 8 0.10000
 [1] 11 0.18000
 [2] 7 1.25000
 [3] 0 1.43000
 [4] 0 3.29000
 [5] 100 5.11000
 [6] 7 7.81000
 [ключ] [значение]
 [0] 0 1.43000
 [1] 0 3.29000
 [2] 7 1.25000
 [3] 7 7.81000
 [4] 8 0.10000
 [5] 11 0.18000
 [6] 100 5.11000
*/

Я использовал простую функцию "сортировки вставкой" из-за ее небольшого размера кода, хотя это не самая быстрая сортировка.

Для большей скорости вам следует заменить ее на QuickSort или гибридную функцию сортировки.

Редактировать:

Вы также можете использовать мою библиотеку introsort для максимальной производительности https://www.mql5.com/en/code/57233.

 

Возможно как-нибудь сделать так, чтобы в define задавать текст без кавычек и использовать его в дальнейшем как строку? Без кавычек ошибка.

#define str aaa

int OnInit()
  {
        string new_str = string(str);
        return INIT_SUCCEEDED;
  }
'aaa' - undeclared identifier   
1 errors, 0 warnings           
 
Andrei Iakovlev #:

Можно ли задать текст без кавычек и использовать его как строку? Без инвертированных запятых возникает ошибка.

Это можно сделать с помощью оператора stringify # внутри макроса:

#define  STR(s) #s

string new_str = STR(Hello MQL);

Print(new_str); // "Hello MQL"

В вашем примере перед использованием оператора # необходимо использовать перенаправление (макрос второго уровня), чтобы расширить макрос 'str' до aaa:

#define  STR(s) #s
#define  STR2(s) STR(s)

#define  str aaa

string new_str = STR2(str);
Print(new_str); // "aaa"

Таким образом, вторая форма с перенаправлением STR2(s) будет совместима независимо от того, является ли параметр "s" строковой константой или другим макросом.