首页 > 其他分享 >unordered_map和map的耗时

unordered_map和map的耗时

时间:2023-04-15 13:24:13浏览次数:35  
标签:float16 map int32 dtype 耗时 diopi unordered float32

在实际生产环境中,遇到使用map还是unordered_map的场景。

  • 一方面,有unordered_map需要自定义hash函数,导致构建时比较复杂。而map使用的是比较运算符来判断元素在map中的位置,std::vector有比较运算符,所以构建map比较简单。
  • 另一方面,unordered_map时hash表,查找时间复杂度为o(1), map为红黑树,查找时间复杂度为o(log2(n)).
    为对比具体的时间差异。故复原了实际场景来测试,代码如下:
#include <stdio.h>
#include <iostream>
#include <map>
#include <unordered_map>
#include <numeric>
#include <vector>
#include <chrono>
#include <random>

enum diopiDtype_t {
    diopi_dtype_bool,
    diopi_dtype_int32,
    diopi_dtype_uint32,
    diopi_dtype_float16,
    diopi_dtype_float32,
    diopi_dtype_float64,
    diopi_dtype_int8,
    diopi_dtype_uint8,
    diopi_dtype_int16,
    diopi_dtype_uint16,
    diopi_dtype_int64,
    diopi_dtype_uint64,

};

std::vector<std::vector<diopiDtype_t>> va{
     {diopi_dtype_bool, diopi_dtype_int32},
    {diopi_dtype_bool, diopi_dtype_float16},
    {diopi_dtype_bool, diopi_dtype_float32},

    {diopi_dtype_int8, diopi_dtype_int16},
    {diopi_dtype_int8, diopi_dtype_int32},
    {diopi_dtype_int8, diopi_dtype_float16},
    {diopi_dtype_int8, diopi_dtype_float32},

    {diopi_dtype_uint8, diopi_dtype_int32},
    {diopi_dtype_uint8, diopi_dtype_int64},
    {diopi_dtype_uint8, diopi_dtype_float16},
    {diopi_dtype_uint8, diopi_dtype_float32},

    {diopi_dtype_int16, diopi_dtype_int32},
    {diopi_dtype_int16, diopi_dtype_float16},
    {diopi_dtype_int16, diopi_dtype_float32},

    {diopi_dtype_int32, diopi_dtype_bool},
    {diopi_dtype_int32, diopi_dtype_int8},
    {diopi_dtype_int32, diopi_dtype_int16},
    {diopi_dtype_int32, diopi_dtype_int64},
    {diopi_dtype_int32, diopi_dtype_float16},
    {diopi_dtype_int32, diopi_dtype_float32},

    {diopi_dtype_uint32, diopi_dtype_int64},
    {diopi_dtype_uint32, diopi_dtype_uint64},

    {diopi_dtype_int64, diopi_dtype_int32},
    {diopi_dtype_int64, diopi_dtype_uint32},
    {diopi_dtype_int64, diopi_dtype_float16},
    {diopi_dtype_int64, diopi_dtype_float32},

    {diopi_dtype_uint64, diopi_dtype_uint32},

    {diopi_dtype_float16, diopi_dtype_bool},
    {diopi_dtype_float16, diopi_dtype_int8},
    {diopi_dtype_float16, diopi_dtype_uint8},
    {diopi_dtype_float16, diopi_dtype_int16},
    {diopi_dtype_float16, diopi_dtype_int32},
    {diopi_dtype_float16, diopi_dtype_int64},
    {diopi_dtype_float16, diopi_dtype_float32},

    {diopi_dtype_float32, diopi_dtype_bool},
    {diopi_dtype_float32, diopi_dtype_int8},
    {diopi_dtype_float32, diopi_dtype_uint8},
    {diopi_dtype_float32, diopi_dtype_int16},
    {diopi_dtype_float32, diopi_dtype_int32},
    {diopi_dtype_float32, diopi_dtype_int64},
    {diopi_dtype_float32, diopi_dtype_float16},
    {diopi_dtype_float32, diopi_dtype_float64},

    {diopi_dtype_float64, diopi_dtype_float32}, 
};

struct HashCnnl {
    size_t operator()(const std::vector<diopiDtype_t>& v) const {
        auto f = [&](auto x1, auto x2){return static_cast<size_t>(x1) ^ static_cast<size_t>(x2);};
        return std::reduce(v.begin(), v.end(), 0, f);
    }
};

template<typename Key, typename Map>
void mp_find(Map mp, std::vector<Key> v, int cnt){
    for (int i = 0; i < cnt; ++i){
        for (size_t j = 0; j < v.size(); ++j){
            mp.find(v[j]);
        }
    }
    return;
}

int main(){
    std::unordered_map<std::vector<diopiDtype_t>, int, HashCnnl> myHashMap;
    std::map<std::vector<diopiDtype_t>, int> myMap;
    for (size_t i = 0; i < va.size(); ++i){
        myHashMap.emplace(va[i], i);
        myMap.emplace(va[i], i);
    }
    
    int cnt = 1000;

    size_t n = va.size();
    auto begin = std::chrono::steady_clock::now();
    mp_find(myMap, va, cnt);
    auto end = std::chrono::steady_clock::now();
    std::chrono::duration<double, std::milli> time_elapse_map(end - begin);

    begin = std::chrono::steady_clock::now();
    mp_find(myHashMap, va, cnt);
    end = std::chrono::steady_clock::now();
    std::chrono::duration<double, std::milli> time_elapse_hashMap(end - begin);

    std::cout << "map: " << time_elapse_map.count() << "ms" << std::endl;
    std::cout << "hashMap: " << time_elapse_hashMap.count() << "ms" << std::endl;
    return 0;
}

运行结果如下:
map: 33.081ms
hashMap: 14.675ms
可见在数据规模(map中的元素个数)为42时,map的时间消耗是unordered_map的两倍多。
可见使用unordered_map更合理。

标签:float16,map,int32,dtype,耗时,diopi,unordered,float32
From: https://www.cnblogs.com/yb-blogs/p/17320933.html

相关文章

  • Java stream实现list转化为map
    在Stream流中将List转换为Map,是使用Collectors.toMap方法来进行转换。key和value都是对象中的某个属性值。Map<String,String>userMap1=userList.stream().collect(Collectors.toMap(User::getId,User::getName));使用箭头函数Map中,key是对象中的某个属性值,value是......
  • Hashmap实现原理
     HashMap线程不安全loadFacter负载因子,默认值为0.75threshold=数组长度*负载因子loadFactorHashMap默认容量initial_capacity:16HashMap数组部分称为哈希桶当链表长度大于等于8时,链表数据将以红黑树的形式进行存储,当长度降到6时,转成链表输入数据计算方法hash(key......
  • Go笔记(七):Map
    map是一种key:value键值对的数据结构容器,通过key检索value,是引用类型。map内部实现是哈希表。1、Map的声明1.1、显示声明1、语法/*声明变量,默认map是nil*/varmap_variablemap[key_data_type]value_data_typemap_variable:map变量名称key_data_type:key......
  • 0007容器之unordered_multiset
    #include<list>#include<iostream>#include<ve......
  • 0008容器之unordered_multimap
    #include<list>#include<iostream>#include<vector>#include<stdexcept>#include<string>#include<cstdlib>//abort()#include<cstdio>//snprintf();整数转字符#include<ctime>#include<algorithm>#include<ar......
  • 09 Shading(Texture Mapping)
    1.TextureMapping下图中,不同位置的反射模型是一样的,但是颜色不同,这是因为漫反射系数不同。同样的,一个点应该还存在着很多属性,那么应当如何定义属性。三维图形的表面可以展开为二维平面,这一个二维平面(包含着对应的三维中三角形的属性)便是Texture。如何实行一个好的纹理映射,是......
  • mapbox-gl实战教程:加载各种底图技巧2
    接续上篇,本篇继续讲mapbox-gl加载各种底图的技巧。五、矢量切片底图加载矢量切片(vectortiles)是随着mapbox-gl产生的一种地图切片格式,相比于之前的影像/图片格式的切片,矢量切片可以在客户端进行样式设置,当用户觉得地图配色等不满足要求时,只需要在客户端调整配置即可。矢量切片加......
  • 08 Shading(Shadding, Pipeline and Texture Mapping)
    关键点Real-TimeRenderingPipelineShader1.Graphics(Real-timeRendering)Pipeline管线1.1PipelineMVP,Rasterization,Z-Buffer,Shading,Texture1.2ShaderPrograms着色器通用程序,用于定义任意像素如何操作。来源[1]Games101.闫令琪......
  • 问题记录:BMap api is not loaded
    原因:mounted初始化时,异步问题导致百度api未引用完就初始化了。解决:修改引入方式,之前在index.html的head引入script标签,现在新建map.js文件。exportfunctionloadBMap(ak){returnnewPromise(function(resolve,reject){if(typeofBMap!=='undefined'){......
  • Mapbox生成热力图
    热力图是一种将数据点分布在坐标轴上的可视化方法,它可以帮助用户更直观地了解数据分布情况。在地理信息系统(GIS)中,热力图可以用于可视化城市规划、交通流量、环境污染等信息。Mapbox是一家提供开源GIS软件的公司,其中包括Mapbox热力图。本文为源GIS将向您介绍Mapbox的特点,以及热力......