#include <array>
#include <cstdint>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <sys/time.h>
double GetCurrentTimeSeconds()
{
timeval tv;
gettimeofday(&tv, NULL);
return double (tv.tv_sec) + 0.000001 * tv.tv_usec;
}
struct Key
{
std::array<uint8_t, 6> MACAddress;
uint16_t EtherType;
};
uint64_t GetKeyValue(Key slowkey)
{
uint64_t key;
std::memcpy(&key, &slowkey, sizeof(key));
return key;
}
union FastKey
{
Key key;
char data[sizeof(Key)];
};
inline uint64_t GetKeyValue(FastKey fastKey)
{
uint64_t key = 0;
key |= uint64_t(fastKey.data[0]) << 56;
key |= uint64_t(fastKey.data[1]) << 48;
key |= uint64_t(fastKey.data[2]) << 40;
key |= uint64_t(fastKey.data[3]) << 32;
key |= uint64_t(fastKey.data[4]) << 24;
key |= uint64_t(fastKey.data[5]) << 16;
key |= uint64_t(fastKey.data[6]) << 8;
key |= uint64_t(fastKey.data[7]) << 0;
return key;
}
template<typename KeyType>
double Test(KeyType inKeyType, uint64_t & preventOptimization)
{
double start = GetCurrentTimeSeconds();
for (uint64_t i = 0; i < 1000000; ++i)
{
preventOptimization += GetKeyValue(inKeyType);
}
return GetCurrentTimeSeconds() - start;
}
Key GetRandomKey()
{
// not really random, but sufficient to prevent
// optimizations from spoiling the benchmark.
Key key;
key.MACAddress[0] = static_cast<uint8_t>(time(0) % 256);
return key;
}
int main()
{
std::cout.setf(std::ios::fixed);
uint64_t preventOptimization = 0;
Key slowKey = GetRandomKey();
std::cout << "Using slow key: " << Test(slowKey, preventOptimization) << " seconds." << std::endl;
std::cout << preventOptimization << std::endl;
FastKey fastKey;
fastKey.key = slowKey;
std::cout << "Using fast key: " << Test(fastKey, preventOptimization) << " seconds." << std::endl;
std::cout << preventOptimization << std::endl;
}