BasesParserSLan/Src/UE/Test.mq5

129 lines
4.3 KiB
MQL5

2026-10-05 17:54:12 -05:00
//+------------------------------------------------------------------+
//| Test.mq5 |
//| Copyright 2026, Niquel Mendoza. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include <TSN\\Tables\\Bits.mqh>
//+------------------------------------------------------------------+
//| Original bitwise/CLZ |
//+------------------------------------------------------------------+
char Utf32_8Len(uint x)
{
const bool y = (x >> 15) != 1;
x |= (1u << 5);
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
const static char rest_t[8] = {0, 0, 0, 0, 1, 2, 3, 4};
const char r = (32 - TSN::g_tsntables_clz32[((x * TSN_TABLES_CLZ_CONSTANT_MAGIC32) >> 27)]) >> 2;
return r - rest_t[r - y];
}
//+------------------------------------------------------------------+
//| Original: suma de comparaciones (sin short-circuit) |
//+------------------------------------------------------------------+
char Utf32_8Len2(uint v)
{
return 1 + (v > 0x7F) + (v > 0x7FF) + (v > 0xFFFF);
}
//+------------------------------------------------------------------+
//| Original: if/else con short-circuit |
//+------------------------------------------------------------------+
char Utf32_8Len3(uint v)
{
if(v < 0x80)
return 1;
else
if(v < 0x800)
return 2;
else
if(v < 0x10000)
return 3;
return 4;
}
//+------------------------------------------------------------------+
//| V4: if/else pero reordenado - chequea primero el caso MAS |
//| probable con distribucion uniforme de 32 bits (v >= 0x10000) |
//+------------------------------------------------------------------+
char Utf32_8Len4(uint v)
{
if(v >= 0x10000)
return 4;
else
if(v >= 0x800)
return 3;
else
if(v >= 0x80)
return 2;
return 1;
}
//+------------------------------------------------------------------+
//| V5: branchless con shifts/clz simple, sin tabla ni magic number |
//| cuenta "cuantos umbrales supera" usando aritmetica de bits pura |
//+------------------------------------------------------------------+
char Utf32_8Len5(uint v)
{
// en vez de 3 comparaciones con bool->int, usamos mascaras directas
// -(x) en complemento a 2 da todo 1s si x!=0, todo 0s si x==0
// pero mas simple: aprovechamos que v>>7, v>>11, v>>16 colapsan a 0
// cuando v es menor al umbral correspondiente
uint m1 = (uint)-(int)((v >> 7) != 0); // todo 1s o todo 0s
uint m2 = (uint)-(int)((v >> 11) != 0);
uint m3 = (uint)-(int)((v >> 16) != 0);
return (char)(1 + (m1 & 1) + (m2 & 1) + (m3 & 1));
}
//+------------------------------------------------------------------+
//| V6: ternarios anidados (el compilador podria tratarlos distinto |
//| a if/else aunque sean logicamente equivalentes) |
//+------------------------------------------------------------------+
char Utf32_8Len6(uint v)
{
return v < 0x80 ? 1 : (v < 0x800 ? 2 : (v < 0x10000 ? 3 : 4));
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int v;
ulong a, b;
const int N = 0xffffff;
#define RUN_TEST(fn) \
MathSrand(1651); \
v = 0; \
a = GetMicrosecondCount(); \
for(int i = 0; i < N; i++) \
{ \
v += fn(uint(MathRand()) & 0xff); \
} \
b = GetMicrosecondCount(); \
Print("time: ", (b - a), " v: ", v, " [" + #fn + "]");
RUN_TEST(Utf32_8Len)
RUN_TEST(Utf32_8Len2)
RUN_TEST(Utf32_8Len3)
RUN_TEST(Utf32_8Len4)
RUN_TEST(Utf32_8Len5)
RUN_TEST(Utf32_8Len6)
#undef RUN_TEST
}
//+------------------------------------------------------------------+