129 lines
No EOL
4.3 KiB
MQL5
129 lines
No EOL
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
| |
}
| |
//+------------------------------------------------------------------+ |