add a simple container-test, speed HifiSockAddr hashing

This commit is contained in:
Stephen Birarda 2015-08-18 11:29:07 -07:00
parent b7d779bb25
commit bf919f105a
4 changed files with 107 additions and 2 deletions

View file

@ -70,10 +70,24 @@ uint qHash(const HifiSockAddr& key, uint seed);
template <>
struct std::hash<HifiSockAddr> {
// NOTE: this hashing specifically ignores IPv6 addresses - if we begin to support those we will need
// to conditionally hash the bytes that represent an IPv6 address
std::size_t operator()(const HifiSockAddr& sockAddr) const {
// use XOR of implemented std::hash templates for new hash
return std::hash<std::string>()(sockAddr.getAddress().toString().toStdString())
^ std::hash<uint16_t>()((uint16_t) sockAddr.getPort());
// depending on the type of address we're looking at
if (sockAddr.getAddress().protocol() == QAbstractSocket::IPv4Protocol) {
return std::hash<uint32_t>()((uint32_t) sockAddr.getAddress().toIPv4Address())
^ std::hash<uint16_t>()((uint16_t) sockAddr.getPort());
} else if (sockAddr.getAddress().protocol() == QAbstractSocket::IPv6Protocol) {
// use XOR of implemented std::hash templates for new hash
return std::hash<char*>()(reinterpret_cast<char*>(sockAddr.getAddress().toIPv6Address().c))
^ std::hash<uint16_t>()((uint16_t) sockAddr.getPort());
} else {
return std::hash<std::string>()(sockAddr.getAddress().toString().toStdString())
^ std::hash<uint16_t>()((uint16_t) sockAddr.getPort());
}
}
};

View file

@ -8,5 +8,8 @@ set_target_properties(scribe PROPERTIES FOLDER "Tools")
add_subdirectory(udt-test)
set_target_properties(udt-test PROPERTIES FOLDER "Tools")
add_subdirectory(container-test)
set_target_properties(container-test PROPERTIES FOLDER "Tools")
add_subdirectory(vhacd-util)
set_target_properties(vhacd-util PROPERTIES FOLDER "Tools")

View file

@ -0,0 +1,4 @@
set(TARGET_NAME container-test)
setup_hifi_project()
link_hifi_libraries(networking)

View file

@ -0,0 +1,84 @@
//
// main.cpp
// tools/container-test/src
//
// Created by Stephen Birarda on 8/18/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#include <algorithm>
#include <chrono>
#include <random>
#include <vector>
#include <unordered_map>
#include <HifiSockAddr.h>
using namespace std::chrono;
int main(int argc, char* argv[]) {
static const int NUM_ELEMENTS = 50;
std::random_device rd;
std::mt19937 generator(rd());
std::uniform_int_distribution<> ipDistribution(1, UINT32_MAX);
std::uniform_int_distribution<> portDistribution(1, UINT16_MAX);
// from 1 to NUM_ELEMENTS, create a vector and unordered map with that many elements and compare how long it takes to pull the last value
for (int i = 1; i <= NUM_ELEMENTS; ++i) {
// create our vector with i elements
std::vector<std::pair<HifiSockAddr, int>> vectorElements(i);
// create our unordered map with i elements
std::unordered_map<HifiSockAddr, int> hashElements;
HifiSockAddr lastAddress;
// fill the structures with HifiSockAddr
for (int j = 0; j < i; ++j) {
// create a random IP address
quint32 randomNumber = ipDistribution(generator);
quint32 randomIP = (randomNumber >> 24 & 0xFF) << 24 |
(randomNumber >> 16 & 0xFF) << 16 |
(randomNumber >> 8 & 0xFF) << 8 |
(randomNumber & 0xFF);
HifiSockAddr randomAddress(QHostAddress(randomIP), portDistribution(generator));
vectorElements.push_back({ randomAddress, 12 });
hashElements.insert({ randomAddress, 12 });
if (j == i - 1) {
// this is the last element - store it for lookup purposes
lastAddress = randomAddress;
}
}
// time how long it takes to get the value for the key lastAddress, for each container
auto before = high_resolution_clock::now();
int vectorResult;
for (auto& vi : vectorElements) {
if (vi.first == lastAddress) {
vectorResult = vi.second;;
break;
}
}
auto vectorDuration = duration_cast<nanoseconds>(high_resolution_clock::now() - before);
Q_UNUSED(vectorResult);
before = high_resolution_clock::now();
auto mi = hashElements.find(lastAddress);
int mapResult = mi->second;
auto mapDuration = duration_cast<nanoseconds>(high_resolution_clock::now() - before);
Q_UNUSED(mapResult);
qDebug() << i << QString("v: %1ns").arg(vectorDuration.count()) << QString("m: %2ns").arg(mapDuration.count());
}
}