#include <iostream>
#include <chrono>
#include <array>
#include <string>
#include <sstream>
#include <iomanip>
template <typename FT>
void timeIt(int count, FT fn) {
auto start = std::chrono::high_resolution_clock::now();
int reg;
uint32_t val;
int size;
for (int iii = 0; iii < count; iii++)
{
reg = iii % 255;
val = iii * (reg * 3 + 7);
size = reg % 4 + 1;
fn(reg, val, size);
}
std::cout << reg << " & " << val << " = " << fn(reg, val, size) << '\n';
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
printf("Time: %lf ms\n", (elapsed.count() / count) * 1000);
}
int main() {
int count = 1000000;
// farnap
timeIt(count, [](int reg, uint32_t val, int size){
static const std::array<std::string, 4> cmdTemps{
"[%.2x]@[%.2x]s",
"[%.2x]@[%.2x]sn[%.2x]s",
"[%.2x]@[%.2x]sn[%.2x]sn[%.2x]s",
"[%.2x]@[%.2x]sn[%.2x]sn[%.2x]sn[%.2x]s"
};
int idx = size - 1;
uint8_t* bytes = (uint8_t*)&val;
int cmdSize = cmdTemps[idx].size() - ((size + 1) * 2);
std::string cmdStr(cmdSize, '\0');
switch (size)
{
case 1:
snprintf(&cmdStr[0], cmdSize + 1, cmdTemps[idx].c_str(), reg, bytes[0]);
break;
case 2:
snprintf(&cmdStr[0], cmdSize + 1, cmdTemps[idx].c_str(), reg, bytes[0], bytes[1]);
break;
case 3:
snprintf(&cmdStr[0], cmdSize + 1, cmdTemps[idx].c_str(), reg, bytes[0], bytes[1], bytes[2]);
break;
case 4:
snprintf(&cmdStr[0], cmdSize + 1, cmdTemps[idx].c_str(), reg, bytes[0], bytes[1], bytes[2], bytes[3]);
break;
}
return cmdStr;
});
// short stack
timeIt(count, [](int reg, uint32_t val, int size){
static const std::array<std::string, 4> cmdTemps{
"[XX]@[XX]s",
"[XX]@[XX]z[XX]s",
"[XX]@[XX]z[XX]z[XX]s",
"[XX]@[XX]z[XX]z[XX]z[XX]s"
};
static const std::string hexDigits = "0123456789abcdef";
uint8_t* bytes = (uint8_t*)&val;
std::string cmdStr(cmdTemps[size-1]);
// reg
cmdStr[1] = hexDigits[reg >> 4];
cmdStr[2] = hexDigits[reg & 0x0f];
switch (size) {
case 1:
cmdStr[6] = hexDigits[bytes[0] >> 4];
cmdStr[7] = hexDigits[bytes[0] & 0xf];
break;
case 2:
cmdStr[6] = hexDigits[bytes[0] >> 4];
cmdStr[7] = hexDigits[bytes[0] & 0xf];
cmdStr[11] = hexDigits[bytes[1] >> 4];
cmdStr[12] = hexDigits[bytes[1] & 0xf];
break;
case 3:
cmdStr[6] = hexDigits[bytes[0] >> 4];
cmdStr[7] = hexDigits[bytes[0] & 0xf];
cmdStr[11] = hexDigits[bytes[1] >> 4];
cmdStr[12] = hexDigits[bytes[1] & 0xf];
cmdStr[16] = hexDigits[bytes[2] >> 4];
cmdStr[17] = hexDigits[bytes[2] & 0xf];
break;
case 4:
cmdStr[6] = hexDigits[bytes[0] >> 4];
cmdStr[7] = hexDigits[bytes[0] & 0xf];
cmdStr[11] = hexDigits[bytes[1] >> 4];
cmdStr[12] = hexDigits[bytes[1] & 0xf];
cmdStr[16] = hexDigits[bytes[2] >> 4];
cmdStr[17] = hexDigits[bytes[2] & 0xf];
cmdStr[21] = hexDigits[bytes[3] >> 4];
cmdStr[22] = hexDigits[bytes[3] & 0xf];
break;
}
return cmdStr;
});
// lapidary
timeIt(count, [](int reg, uint32_t val, int size){
static const std::array<std::string, 4> cmdTemps{
"[XX]@[XX]s",
"[XX]@[XX]z[XX]s",
"[XX]@[XX]z[XX]z[XX]s",
"[XX]@[XX]z[XX]z[XX]z[XX]s"
};
static const std::string hexDigits = "0123456789abcdef";
uint8_t* bytes = (uint8_t*)&val;
std::string cmdStr(cmdTemps[size-1]);
// reg
cmdStr[1] = hexDigits[reg >> 4];
cmdStr[2] = hexDigits[reg & 0x0f];
for (int pos = 6, iii = 0; iii < size; iii++, pos += 5)
{
cmdStr[pos] = hexDigits[bytes[iii] >> 4];
cmdStr[pos+1] = hexDigits[bytes[iii] & 0xf];
}
return cmdStr;
});
// leopard
timeIt(count, [](int reg, uint32_t val, int size){
static const std::array<std::string, 4> cmdTemps{
"[XX]@[XX]s",
"[XX]@[XX]z[XX]s",
"[XX]@[XX]z[XX]z[XX]s",
"[XX]@[XX]z[XX]z[XX]z[XX]s"
};
static const std::string hexDigits = "0123456789abcdef";
uint8_t* bytes = (uint8_t*)&val;
std::string cmdStr(cmdTemps[size-1]);
// reg
cmdStr[1] = hexDigits[reg >> 4];
cmdStr[2] = hexDigits[reg & 0x0f];
for (int pos = 6, iii = 0; iii < size; iii++, pos += 5)
{
cmdStr[pos] = hexDigits[bytes[iii] >> 4];
cmdStr[pos+1] = hexDigits[bytes[iii] & 0xf];
}
return cmdStr;
});
return 0;
}