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

 
amrali #:
Wrong!

I write in the Russian-language thread, which is automatically translated into the English-language thread that you read.

Unfortunately, deleting the erroneous post in the Russian-language thread had no effect on the English-language thread.

 
amrali #:
2. Faster access times that were achieved here are never due to an object or a structure, it is merely due to compiler's optimization for the "switch" statement.

3. Optimization of switch depends on the number of cases + optimization mode. Large number or complex switches do not get this jump table optimization and will remain as multiple if-else.

4. Lookup table using an array will always be the standard and the most reliable method not depending on the number of cases, their complexity or the compiler's optimization mode.
int Lookup_Table(int x)
  {
   static int table[16] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150};
   return table[x];
  }

// When compiling an small to medium switch with consecutive cases (0 to n), under
// optimization mode, the compiler converts the series of these multiple if-else
// statements O(n) into a jump table, where an array of pointers to code blocks
// is indexed using the cases number at runtime, giving O(1) direct access similar
// to the lookup table using an array.
int Switch(int x)
  {
   switch(x)
     {
      case 0: return 0;
      case 1: return 10;
      case 2: return 20;
      case 3: return 30;
      case 4: return 40;
      case 5: return 50;
      case 6: return 60;
      case 7: return 70;
      case 8: return 80;
      case 9: return 90;
      case 10: return 100;
      case 11: return 110;
      case 12: return 120;
      case 13: return 130;
      case 14: return 140;
      case 15: return 150;
     }
   return -1;
  }

void OnStart()
  {
   long sum1 = 0;
   long sum2 = 0;
   int slots = 16;
   int test_count = 1e8;

   int seed = MathRand();

   ulong time1 = GetMicrosecondCount();
   for(int i = 0; i < test_count; i++)
      for(int x = 0; x < slots; x++) {
         //int j = (x * 7 + seed) % slots;  // uncomment two lines to test lookups in a random order (Miller Shuffle algorithm)
         //sum1 += Lookup_Table(j);         // in a real situation, the lookups are not sequential
         sum1 += Lookup_Table(x);
      }
   time1 = GetMicrosecondCount() - time1;
   PrintFormat("%6ull microsec,  sum:%ull %s", time1, sum1, " // Lookup table");

   ulong time2 = GetMicrosecondCount();
   for(int i = 0; i < test_count; i++)
      for(int x = 0; x < slots; x++) {
         //int j = (x * 7 + seed) % slots;
         //sum2 += Switch(j);
         sum2 += Switch(x);
      }
   time2 = GetMicrosecondCount() - time2;
   PrintFormat("%6ull microsec,  sum:%ull %s", time2, sum2, " // Switch statement");
  }

Maximum Optimization:

//  43834ll microsec,  sum:4035883008ll  // Lookup table
//   6179ll microsec,  sum:4035883008ll  // Switch statement

Faster access times are due to the generated jump table under the full optimization mode.

No Optimization:

// 2636121ll microsec,  sum:4035883008ll  // Lookup table
// 4120042ll microsec,  sum:4035883008ll  // Switch statement