Features of the mql5 language, subtleties and tricks - page 137

 
Alexey Navoykov:
It does not seem to be about arithmetic operations, because there are none, all values are computed at the compilation stage. The reason is the presence of a loop with an unknown number of iterations (although these iterations average less than two). So your code is somehow optimized by a known number of rand() calls

https://www.mql5.com/ru/forum/308881/page3#comment_11222192

 
Vict:

What do processor developers have to do with it? The generator is software implemented.

No, it's not. This generator is implemented in hardware. This speed cannot be achieved by software - that's obvious.

 
Nikolai Semko:

No, of course not. This generator is implemented in hardware. This speed cannot be achieved by software - it's obvious.

Actually, the hardware implement a RAND() generator, while rand() is a pseudorandom one.

MathRand

Returns a pseudo-random integer in range 0 to 32767.

I'm not very familiar with hardware, but you'll probably be disappointed - it doesn't seem to work very fast, it's only good as a seed for pseudorandom.
 
Vict:

Well, actually, the hardware implements a RAND() generator, while rand() is a pseudo-random one, it's written in the handbook

I'm not very familiar with the hardware one, but you'll probably be disappointed - it doesn't seem to run very fast, it's only good as seed for pseudorandom.

clearly - pseudo.

Random is much slower(https://en.wikipedia.org/wiki/RdRand)

 
Nikolai Semko:

Clearly pseudo.

random runs much slower(https://en.wikipedia.org/wiki/RdRand)

Well, yes, pseudo is also shoved in. But I'm sure - rand() is implemented programmatically. Perhaps one of the "older" comrades passing by will confirm it.

 
Vict:

Well, yes, they've put in a pseudo too. But I'm sure - rand() is implemented programmatically. Perhaps one of the "older" comrades passing by will confirm it.

I don't exclude that you may be right. If I have a spare minute, I will try to implement something similar. Although I doubt that I can do it in a nanosecond, but if I can get away from cycles, I think I can do it in 5.
 
Vict:

But I'm sure - rand() is implemented programmatically. Perhaps one of the "older" comrades passing by will confirm it.

Yes, perhaps you're right.
This variant of rand16() function generating pre-random numbers works less than half as slow as the original function and generates random numbers from 0 to 65535.

ushort rand16() { return(((ushort)rand8()<<8)|(ushort)rand8());}


uchar rand8()
{
    staticushort s[10] = { 0x52, 0x8e, 0xdc, 0x61, 0x35, 0xbc, 0x5c, 0xb6 };
    staticushort c = 0xa6;
    staticint i = 0;
    ushort t;
    uchar x;
    
    x = (uchar)s[i];
    t = (ushort)x  + c;
    c = t >> 8;
    c += x;
    x = (uchar)t & 255;
    s[i] = x;
    i++;
    i=i&7;
    return x;
}

i.e. less than 2 nanoseconds.

2019.06.09 23:52:15.855 TestSpeedRand (US30Index,H1)    Время формирования случайных массивов = 9068  микросекунд. Всего сгенерировано 4655770 случайных чисел rand()
2019.06.09 23:52:17.892 TestSpeedRand (US30Index,H1)    Время формирования случайных массивов = 16562 микросекунд. Всего сгенерировано 4655770 случайных чисел rand16()
2019.06.09 23:52:19.940 TestSpeedRand (US30Index,H1)    Время формирования случайных массивов = 22299 микросекунд. Всего сгенерировано 4655770 случайных чисел get_rand()
2019.06.09 23:52:21.986 TestSpeedRand (US30Index,H1)    Время формирования случайных массивов = 20094 микросекунд. Всего сгенерировано 4655770 случайных чисел randUlong()
2019.06.09 23:52:24.020 TestSpeedRand (US30Index,H1)    Время формирования случайных массивов = 14660 микросекунд. Всего сгенерировано 4655770 случайных чисел randUint()
2019.06.09 23:52:26.053 TestSpeedRand (US30Index,H1)    Время формирования случайных массивов = 12543 микросекунд. Всего сгенерировано 4655770 случайных чисел randShort()
2019.06.09 23:52:28.095 TestSpeedRand (US30Index,H1)    Время формирования случайных массивов = 20883 микросекунд. Всего сгенерировано 4655770 случайных чисел RandomLong()
Files:
 
// Некоторые возможности структур, которых нет у классов.

// #define struct class // Смотрим ошибки, которые возникают при замене структур на классы.

struct A
{
public:  
  int i;
  
  uint Save( const int handle) { return(FileWriteStruct(handle, this)); } // Запись себя
  uint Load( const int handle) { return(FileReadStruct(handle, this)); }  // Чтение себя
};

// Использование в объединениях
union UNION
{
  uchar b1[sizeof(A)];
  A b2;
};

// Выравнивание
struct pack(sizeof(A)) B : public A
{
  short j;
};

// Структура со скрытым полем
struct C : private A
{
public:  
  void Set( const int Num ) { this.i = Num; }  
  int Get( void ) const { return(this.i); }  
};

// Структура с неизменяемым полем.
struct D
{
public:  
  const A a;
};

template <typename T1, typename T2>
void FromTo( const T1 &ValueFrom, T2 &ValueTo )
{
  uchar Bytes[];    

  StructToCharArray(ValueFrom, Bytes); // В массив байтов
  CharArrayToStruct(ValueTo, Bytes);   // Из массива байтов  
}

void OnStart()
{
  A a[1] = {0};
  
  FileReadArray(0, a);  // Чтение массива
  FileWriteArray(0, a); // Запись массива

  ArrayCopy(a, a); // Копирование массивов
  ZeroMemory(a);   // Обнуление массивов
    
  C c; // Структура со скрытым полем
  c.Set(7);

  FromTo(c, a[0]);
  Print(a[0].i); // Достали значение приватного поля из C.
  
  D d; // Структура с неизменяемым полем.

  a[0].i = 5;
  
  FromTo(a[0], d);
  Print(d.a.i); // Изменили const-поле.    

  FromTo(a[0], c);
  Print(c.Get()); // Изменили private-поле.    
}
In addition, the class object is 16 bytes larger than the object of a similar POD structure. That is, arrays of structures are even more economical.
 
fxsaber:
In addition, the class object is 16 bytes larger than the object of a similar POD structure. Thus, arrays of structures are even more economical.
Class!
 
One of the answers to the question in the quoted thread title

Forum on trading, automated trading systems and testing trading strategies

What is different between Symbol() and _Symbol

fxsaber, 2019.07.07 14:47

void Func( const string& ) {}

void OnStart()
{
  Func(Symbol()); // ERROR: 'Symbol' - parameter passed as reference, variable expected
  Func(_Symbol);  // OK   
}

If Symbol() is called inside a class/structure without ::, it might be more convenient than a predefined variable, as you can make a quick substitution by declaring a method with the same name.

Reason: