#include <iostream>
#include <unordered_map>
#include <time.h>
#include <wchar.h>
#include <chrono>
#include <thread>
#include <vector>
#include <array>
#include <stdlib.h>
#include <string.h>
using namespace std;
namespace me{
using tint = unsigned long;//ideone жалуется на tint
using nint = long long;
template <typename K,typename T,typename _hash= std::hash<K>>
struct unordered_map{
tint *data;//Вся информация
struct key{
K first;
T second;
tint next;
};
key *pi;//Полезная информация
tint clv=0;// количество
tint buck;
tint size;
void resize(tint n){
size=n;
data=(decltype(data))realloc(data,n);
pi=(key*)(nint((void*)data)+sizeof(tint)*buck)-1;
}
unordered_map(int a):buck(a),data(nullptr){
// data=malloc();
resize(sizeof(tint)*buck+buck*sizeof(key)/2);
for (tint i=0;i<buck;i++)
((tint*)data)[i]=0;
}
unordered_map():unordered_map(4){}
tint hash(K& a)const{
// return 0;
return _hash()(a)%buck;
}
void insert(std::pair<K,T> a){
if (size<sizeof(tint)*buck+sizeof(key)*(5+clv))
resize(size*2);
tint y=hash(a.first);
// wprintf(L"insert pair %f [hash=%d] %d ------------\n",*(float*)a.first.p,y,a.second);
// prn();
tint* w=&data[y];
// wprintf(L"]]");
// wprintf(L":%d:",*w);
while (*w){
//pi[w]
w=&pi[*w].next;
// wprintf(L":%d:",*w);
}
// wprintf(L"[[===========\n");
clv++;
key* me=&pi[clv];
me->first=a.first;
me->second=a.second;
me->next=0;
*w=clv;
}
key* find(K a){
tint y=hash(a);
tint* w=&data[y];
while (*w){
//pi[w]
if (pi[*w].first==a){
return &pi[*w];
}
w=&pi[*w].next;
}
return nullptr;
}
~unordered_map(){
free(data);
}
};
inline nint rdtsc()
{
static tint lo, hi;
asm volatile("rdtsc\n"
: "=a"(lo), "=d"(hi));
return ((nint)hi << 32) | lo;
}
}
double hz;
void test(me::tint N,me::tint seed){
wprintf(L"\n\n N: %d seed: %d\n",N,seed);
using namespace me;
tint c1,c2;
nint t1,t2;
struct mm{ //Какая-то временная структура
int n;//а тут их количество
float* p;//Вот тут лежат флоаты
size_t operator()(const mm& a) const{
size_t t=1231231;
for (int i=0;i<a.n;i++)
t^=std::hash<float>()(a.p[i])<<i;
return t;
};
bool operator ==(const mm& a)const {
if (a.n!=n)return false;
for (int i=0;i<n;i++)
if (a.p[i]!=p[i])
return false;
return true;
}
};
std::vector<std::array<float,8>> ms{N};
srand(seed);
for (int i=0;i<N;i++){
ms[i][0]=rand()%(N/2);
for (int t=1;t<ms[i].size();t++)
ms[i][t]=0;
}
std::vector<mm> arr{N};
for (int i=0;i<N;i++){
arr[i].n=8;
arr[i].p=(decltype(arr[i].p))(&ms[i]);
}
double e1,m1,e2,m2;
std::vector<tint> ind(N);//Здесь индексы
std::vector<float> ver(sizeof(float)*8*N);//Здесь вершины
int j;//Количество добавленных
auto std=[&]
{
j=0;
c1=clock();t1=rdtsc();
std::unordered_map<mm,tint,mm> kk(N);
for (int i=0;i<N;i++)
{
auto r=kk.find(arr[i]);
if (r==kk.cend()){//Если такого ещё нет
memcpy(&ver[j*8],arr[i].p,sizeof(float)*8);
ind[i]=j;
kk.insert({arr[i],j});
j++;
}
else
{
ind[i]=r->second;//kk[aa[i]]; }
}
}
c2=clock();t2=rdtsc();
wprintf(L"N: %d j: %d\n",N,j);
wprintf(L"std | %d ms [%.2f] : %lldk\n",c2-c1,(t2-t1)/hz,t2-t1);
m1=c2-c1;
e1=t2-t1;
};
auto me=[&]
{
j=0;
c1=clock();t1=rdtsc();
me::unordered_map<mm,tint,mm> kk(N);
for (int i=0;i<N;i++)
{
// kk.prn();
auto r=kk.find(arr[i]);
if (r==nullptr){//Если такого ещё нет
memcpy(&ver[j*8],arr[i].p,sizeof(float)*8);
ind[i]=j;
kk.insert({arr[i],j});
j++;
}
else
{
ind[i]=r->second;//kk[aa[i]]; }
}
// wprintf(L"\n");
}
c2=clock();t2=rdtsc();
wprintf(L"N: %d j: %d\n ",N,j);
wprintf(L"me | %d ms [%.2f] : %lldk\n",c2-c1,(t2-t1)/hz,t2-t1);
m2=c2-c1;
e2=t2-t1;
};
std();
me();
wprintf(L" %.2f%% %.2f%%\n",100.0*m1/m2,100.0*e1/e2);
me();
std();
wprintf(L" %.2f%% %.2f%%\n",100.0*m1/m2,100.0*e1/e2);
}
int main()
{
using namespace me;
tint c1=clock();
nint t1=me::rdtsc();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
tint c2=clock();
nint t2=me::rdtsc();
hz=double(t2-t1)/(c2-c1);
wprintf(L"khz: %.2f\n",hz);
test(1000000,123);
test(1000,52);
test(10,76);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgPHdjaGFyLmg+CiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDx0aHJlYWQ+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxhcnJheT4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCm5hbWVzcGFjZSBtZXsKCiAgIHVzaW5nIHRpbnQgPSB1bnNpZ25lZCBsb25nOy8vaWRlb25lINC20LDQu9GD0LXRgtGB0Y8g0L3QsCB0aW50CiAgIHVzaW5nIG5pbnQgPSBsb25nIGxvbmc7CgogICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSyx0eXBlbmFtZSBULHR5cGVuYW1lIF9oYXNoPSBzdGQ6Omhhc2g8Sz4+CiAgIHN0cnVjdCB1bm9yZGVyZWRfbWFwewogICAgICB0aW50ICpkYXRhOy8v0JLRgdGPINC40L3RhNC+0YDQvNCw0YbQuNGPCgogICAgICBzdHJ1Y3Qga2V5ewogICAgICAgICBLIGZpcnN0OwogICAgICAgICBUIHNlY29uZDsKICAgICAgICAgdGludCBuZXh0OwogICAgICB9OwogICAgICBrZXkgKnBpOy8v0J/QvtC70LXQt9C90LDRjyDQuNC90YTQvtGA0LzQsNGG0LjRjwogICAgICB0aW50IGNsdj0wOy8vINC60L7Qu9C40YfQtdGB0YLQstC+CgogICAgICB0aW50IGJ1Y2s7CiAgICAgIHRpbnQgc2l6ZTsKCiAgICAgIHZvaWQgcmVzaXplKHRpbnQgbil7CiAgICAgICAgIHNpemU9bjsKICAgICAgICAgZGF0YT0oZGVjbHR5cGUoZGF0YSkpcmVhbGxvYyhkYXRhLG4pOwogICAgICAgICBwaT0oa2V5KikobmludCgodm9pZCopZGF0YSkrc2l6ZW9mKHRpbnQpKmJ1Y2spLTE7CgogICAgICB9CgogICAgICB1bm9yZGVyZWRfbWFwKGludCBhKTpidWNrKGEpLGRhdGEobnVsbHB0cil7CiAgICAgICAgIC8vICBkYXRhPW1hbGxvYygpOwogICAgICAgICByZXNpemUoc2l6ZW9mKHRpbnQpKmJ1Y2srYnVjaypzaXplb2Yoa2V5KS8yKTsKICAgICAgICAgZm9yICh0aW50IGk9MDtpPGJ1Y2s7aSsrKQogICAgICAgICAgICAoKHRpbnQqKWRhdGEpW2ldPTA7CiAgICAgIH0KICAgICAgdW5vcmRlcmVkX21hcCgpOnVub3JkZXJlZF9tYXAoNCl7fQoKCgogICAgICB0aW50IGhhc2goSyYgYSljb25zdHsKICAgICAgICAgLy8gcmV0dXJuIDA7CiAgICAgICAgIHJldHVybiBfaGFzaCgpKGEpJWJ1Y2s7CiAgICAgIH0KICAgICAgdm9pZCBpbnNlcnQoc3RkOjpwYWlyPEssVD4gYSl7CgogICAgICAgICBpZiAoc2l6ZTxzaXplb2YodGludCkqYnVjaytzaXplb2Yoa2V5KSooNStjbHYpKQogICAgICAgICAgICByZXNpemUoc2l6ZSoyKTsKICAgICAgICAgdGludCB5PWhhc2goYS5maXJzdCk7CiAgICAgICAgIC8vICB3cHJpbnRmKEwiaW5zZXJ0IHBhaXIgJWYgW2hhc2g9JWRdICVkIC0tLS0tLS0tLS0tLVxuIiwqKGZsb2F0KilhLmZpcnN0LnAseSxhLnNlY29uZCk7CiAgICAgICAgIC8vICAgcHJuKCk7CiAgICAgICAgIHRpbnQqIHc9JmRhdGFbeV07CiAgICAgICAgIC8vICB3cHJpbnRmKEwiXV0iKTsKICAgICAgICAgLy8gICB3cHJpbnRmKEwiOiVkOiIsKncpOwogICAgICAgICB3aGlsZSAoKncpewogICAgICAgICAgICAvL3BpW3ddCiAgICAgICAgICAgIHc9JnBpWyp3XS5uZXh0OwogICAgICAgICAgICAvLyAgIHdwcmludGYoTCI6JWQ6Iiwqdyk7CiAgICAgICAgIH0KICAgICAgICAgLy8gICAgd3ByaW50ZihMIltbPT09PT09PT09PT1cbiIpOwoKCgogICAgICAgICBjbHYrKzsKICAgICAgICAga2V5KiBtZT0mcGlbY2x2XTsKICAgICAgICAgbWUtPmZpcnN0PWEuZmlyc3Q7CiAgICAgICAgIG1lLT5zZWNvbmQ9YS5zZWNvbmQ7CiAgICAgICAgIG1lLT5uZXh0PTA7CiAgICAgICAgICp3PWNsdjsKCiAgICAgIH0KCiAgICAgIGtleSogZmluZChLIGEpewogICAgICAgICB0aW50IHk9aGFzaChhKTsKICAgICAgICAgdGludCogdz0mZGF0YVt5XTsKICAgICAgICAgd2hpbGUgKCp3KXsKICAgICAgICAgICAgLy9waVt3XQogICAgICAgICAgICBpZiAocGlbKnddLmZpcnN0PT1hKXsKICAgICAgICAgICAgICAgcmV0dXJuICZwaVsqd107CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdz0mcGlbKnddLm5leHQ7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIG51bGxwdHI7CiAgICAgIH0KCgogICAgICB+dW5vcmRlcmVkX21hcCgpewogICAgICAgICBmcmVlKGRhdGEpOwogICAgICB9CgoKCgogICB9OwoKICAgaW5saW5lIG5pbnQgcmR0c2MoKQogICB7CiAgICAgIHN0YXRpYyB0aW50IGxvLCBoaTsKICAgICAgYXNtIHZvbGF0aWxlKCJyZHRzY1xuIgogICAgICAgICAgICAgICAgICAgOiAiPWEiKGxvKSwgIj1kIihoaSkpOwogICAgICByZXR1cm4gKChuaW50KWhpIDw8IDMyKSB8IGxvOwogICB9Cgp9Cgpkb3VibGUgaHo7Cgp2b2lkIHRlc3QobWU6OnRpbnQgTixtZTo6dGludCBzZWVkKXsKCiAgIHdwcmludGYoTCJcblxuICAgICBOOiAlZCAgICBzZWVkOiAlZFxuIixOLHNlZWQpOwogICB1c2luZyBuYW1lc3BhY2UgbWU7CiAgIHRpbnQgYzEsYzI7CiAgIG5pbnQgdDEsdDI7CiAgIHN0cnVjdCBtbXsgIC8v0JrQsNC60LDRjy3RgtC+INCy0YDQtdC80LXQvdC90LDRjyDRgdGC0YDRg9C60YLRg9GA0LAKICAgICAgaW50IG47Ly/QsCDRgtGD0YIg0LjRhSDQutC+0LvQuNGH0LXRgdGC0LLQvgogICAgICBmbG9hdCogcDsvL9CS0L7RgiDRgtGD0YIg0LvQtdC20LDRgiDRhNC70L7QsNGC0YsKICAgICAgc2l6ZV90IG9wZXJhdG9yKCkoY29uc3QgbW0mIGEpIGNvbnN0ewogICAgICAgICBzaXplX3QgdD0xMjMxMjMxOwoKICAgICAgICAgZm9yIChpbnQgaT0wO2k8YS5uO2krKykKICAgICAgICAgICAgdF49c3RkOjpoYXNoPGZsb2F0PigpKGEucFtpXSk8PGk7CiAgICAgICAgIHJldHVybiB0OwogICAgICB9OwogICAgICBib29sIG9wZXJhdG9yID09KGNvbnN0IG1tJiBhKWNvbnN0IHsKICAgICAgICAgaWYgKGEubiE9bilyZXR1cm4gZmFsc2U7CiAgICAgICAgIGZvciAoaW50IGk9MDtpPG47aSsrKQogICAgICAgICAgICBpZiAoYS5wW2ldIT1wW2ldKQogICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgfQogICB9OwoKCgogICBzdGQ6OnZlY3RvcjxzdGQ6OmFycmF5PGZsb2F0LDg+PiBtc3tOfTsKICAgc3JhbmQoc2VlZCk7CiAgIGZvciAoaW50IGk9MDtpPE47aSsrKXsKICAgICAgbXNbaV1bMF09cmFuZCgpJShOLzIpOwogICAgICBmb3IgKGludCB0PTE7dDxtc1tpXS5zaXplKCk7dCsrKQogICAgICAgICBtc1tpXVt0XT0wOwogICB9CgogICBzdGQ6OnZlY3RvcjxtbT4gYXJye059OwoKICAgZm9yIChpbnQgaT0wO2k8TjtpKyspewogICAgICBhcnJbaV0ubj04OwogICAgICBhcnJbaV0ucD0oZGVjbHR5cGUoYXJyW2ldLnApKSgmbXNbaV0pOwogICB9CgoKICAgZG91YmxlIGUxLG0xLGUyLG0yOwoKICAgc3RkOjp2ZWN0b3I8dGludD4gaW5kKE4pOy8v0JfQtNC10YHRjCDQuNC90LTQtdC60YHRiwogICBzdGQ6OnZlY3RvcjxmbG9hdD4gdmVyKHNpemVvZihmbG9hdCkqOCpOKTsvL9CX0LTQtdGB0Ywg0LLQtdGA0YjQuNC90YsKICAgaW50IGo7Ly/QmtC+0LvQuNGH0LXRgdGC0LLQviDQtNC+0LHQsNCy0LvQtdC90L3Ri9GFCgogICBhdXRvIHN0ZD1bJl0KICAgewogICAgICBqPTA7CiAgICAgIGMxPWNsb2NrKCk7dDE9cmR0c2MoKTsKICAgICAgc3RkOjp1bm9yZGVyZWRfbWFwPG1tLHRpbnQsbW0+IGtrKE4pOwogICAgICBmb3IgKGludCBpPTA7aTxOO2krKykKICAgICAgewoKICAgICAgICAgYXV0byByPWtrLmZpbmQoYXJyW2ldKTsKICAgICAgICAgaWYgKHI9PWtrLmNlbmQoKSl7Ly/QldGB0LvQuCDRgtCw0LrQvtCz0L4g0LXRidGRINC90LXRggogICAgICAgICAgICBtZW1jcHkoJnZlcltqKjhdLGFycltpXS5wLHNpemVvZihmbG9hdCkqOCk7CiAgICAgICAgICAgIGluZFtpXT1qOwogICAgICAgICAgICBray5pbnNlcnQoe2FycltpXSxqfSk7CiAgICAgICAgICAgIGorKzsKICAgICAgICAgfQogICAgICAgICBlbHNlCiAgICAgICAgIHsKICAgICAgICAgICAgaW5kW2ldPXItPnNlY29uZDsvL2trW2FhW2ldXTsgIH0KICAgICAgICAgfQoKICAgICAgfQogICAgICBjMj1jbG9jaygpO3QyPXJkdHNjKCk7CiAgICAgIHdwcmludGYoTCJOOiAlZCAgICBqOiAlZFxuIixOLGopOwogICAgICB3cHJpbnRmKEwic3RkIHwgJWQgbXMgWyUuMmZdIDogICVsbGRrXG4iLGMyLWMxLCh0Mi10MSkvaHosdDItdDEpOwogICAgICBtMT1jMi1jMTsKICAgICAgZTE9dDItdDE7CiAgIH07CgoKCgogICBhdXRvIG1lPVsmXQogICB7CiAgICAgIGo9MDsKICAgICAgYzE9Y2xvY2soKTt0MT1yZHRzYygpOwogICAgICBtZTo6dW5vcmRlcmVkX21hcDxtbSx0aW50LG1tPiBrayhOKTsKICAgICAgZm9yIChpbnQgaT0wO2k8TjtpKyspCiAgICAgIHsKCiAgICAgICAgIC8vIGtrLnBybigpOwogICAgICAgICBhdXRvIHI9a2suZmluZChhcnJbaV0pOwogICAgICAgICBpZiAocj09bnVsbHB0cil7Ly/QldGB0LvQuCDRgtCw0LrQvtCz0L4g0LXRidGRINC90LXRggogICAgICAgICAgICBtZW1jcHkoJnZlcltqKjhdLGFycltpXS5wLHNpemVvZihmbG9hdCkqOCk7CiAgICAgICAgICAgIGluZFtpXT1qOwogICAgICAgICAgICBray5pbnNlcnQoe2FycltpXSxqfSk7CiAgICAgICAgICAgIGorKzsKICAgICAgICAgfQogICAgICAgICBlbHNlCiAgICAgICAgIHsKICAgICAgICAgICAgaW5kW2ldPXItPnNlY29uZDsvL2trW2FhW2ldXTsgIH0KICAgICAgICAgfQogICAgICAgICAvLyB3cHJpbnRmKEwiXG4iKTsKICAgICAgfQogICAgICBjMj1jbG9jaygpO3QyPXJkdHNjKCk7CiAgICAgIHdwcmludGYoTCJOOiAlZCAgICBqOiAlZFxuICIsTixqKTsKICAgICAgd3ByaW50ZihMIm1lIHwgJWQgbXMgWyUuMmZdIDogICVsbGRrXG4iLGMyLWMxLCh0Mi10MSkvaHosdDItdDEpOwogICAgICBtMj1jMi1jMTsKICAgICAgZTI9dDItdDE7CiAgIH07CgoKICAgc3RkKCk7CiAgIG1lKCk7CiAgIHdwcmludGYoTCIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlLjJmJSUgICUuMmYlJVxuIiwxMDAuMCptMS9tMiwxMDAuMCplMS9lMik7CiAgIG1lKCk7CiAgIHN0ZCgpOwogICB3cHJpbnRmKEwiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJS4yZiUlICAlLjJmJSVcbiIsMTAwLjAqbTEvbTIsMTAwLjAqZTEvZTIpOwoKCn0KCmludCBtYWluKCkKewogICB1c2luZyBuYW1lc3BhY2UgbWU7CgogICB0aW50IGMxPWNsb2NrKCk7CiAgIG5pbnQgdDE9bWU6OnJkdHNjKCk7CiAgIHN0ZDo6dGhpc190aHJlYWQ6OnNsZWVwX2ZvcihzdGQ6OmNocm9ubzo6bWlsbGlzZWNvbmRzKDEwMCkpOwogICB0aW50IGMyPWNsb2NrKCk7CiAgIG5pbnQgdDI9bWU6OnJkdHNjKCk7CiAgIGh6PWRvdWJsZSh0Mi10MSkvKGMyLWMxKTsKICAgd3ByaW50ZihMImtoejogJS4yZlxuIixoeik7CgogICB0ZXN0KDEwMDAwMDAsMTIzKTsKICAgdGVzdCgxMDAwLDUyKTsKICAgdGVzdCgxMCw3Nik7CgoKfQo=