forked from nique_372/BasesParserSLan
129 lines
4.3 KiB
MQL5
129 lines
4.3 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| 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
| |||
}
| |||
//+------------------------------------------------------------------+
|