Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将散列值传递到无序映射以减少持有的时间锁?_C++_Multithreading_Optimization_Hash_Std - Fatal编程技术网

C++ 如何将散列值传递到无序映射以减少持有的时间锁?

C++ 如何将散列值传递到无序映射以减少持有的时间锁?,c++,multithreading,optimization,hash,std,C++,Multithreading,Optimization,Hash,Std,我把一张无序的地图包在锁里 多个线程正在进行查找、插入。因此需要一把锁 我的问题是,我不希望散列计算在无序映射代码中进行,因为散列函数确实需要时间,所以不必要地持有锁 我的想法是让调用方在锁外计算散列,并在查找、插入期间将其传递到无序映射中 这是否可能与标准无序地图 您可以预先计算哈希并将其存储在密钥中,然后在映射的互斥锁被锁定时使用自定义哈希函数检索它: #include <iostream> #include <unordered_map> #include <

我把一张无序的地图包在锁里

多个线程正在进行查找、插入。因此需要一把锁

我的问题是,我不希望散列计算在无序映射代码中进行,因为散列函数确实需要时间,所以不必要地持有锁

我的想法是让调用方在锁外计算散列,并在查找、插入期间将其传递到无序映射中


这是否可能与标准无序地图

您可以预先计算哈希并将其存储在密钥中,然后在映射的互斥锁被锁定时使用自定义哈希函数检索它:

#include <iostream>
#include <unordered_map>
#include <string>
#include <utility>

struct custom_key
{
    custom_key(std::string s)
    : data(std::move(s))
    , hash_value(compute_hash(data))
    {}

    const std::string data;

    static std::size_t compute_hash(const std::string& dat) {
        return std::hash<std::string>()(dat);
    }

    // pre-computed hash
    const std::size_t hash_value;
};

bool operator==(const custom_key& l, const custom_key& r) {
    return l.data == r.data;
}

namespace std {
    template<> struct hash<custom_key> {
        using argument_type = custom_key;
        using result_type = size_t;
        result_type operator()(const argument_type& k) const {
            return k.hash_value;
        }
    };
}
using namespace std;

auto main() -> int
{
    unordered_map<custom_key, std::string> m;

    m.emplace(custom_key("k1"s), "Hello, World");

    return 0;
}
#包括
#包括
#包括
#包括
结构自定义密钥
{
自定义_键(标准::字符串s)
:数据(标准::移动)
,哈希值(计算哈希(数据))
{}
常量std::字符串数据;
静态标准::大小\u t计算\u散列(常量标准::字符串和数据){
返回std::hash()(dat);
}
//预计算散列
const std::size\u t散列值;
};
布尔运算符==(常数自定义键&l,常数自定义键&r){
返回l.data==r.data;
}
名称空间标准{
模板结构哈希{
使用参数\类型=自定义\键;
使用结果类型=大小t;
结果类型运算符()(常量参数类型&k)常量{
返回k.hash_值;
}
};
}
使用名称空间std;
auto main()->int
{
无序地图m;
m、 安置(定制钥匙(“k1”s),“你好,世界”);
返回0;
}
更新:

回顾这个答案后,我想到我们可以做得更好:

#include <iostream>
#include <unordered_map>
#include <string>
#include <utility>


/* the precompute key type */

template<class Type>
struct precompute_key {

    /* may be constructed with any of the constructors of the underlying type */
    template<class...Args>
    precompute_key(Args &&...args)
            : value_(std::forward<Args>(args)...), hash_(std::hash<Type>()(value_)) {}

    operator Type &() { return value_; }

    operator Type const &() const { return value_; }

    auto hash_value() const { return hash_; }

    auto value() const { return value_; }

    auto value() { return value_; }

private:
    Type value_;
    std::size_t hash_;
};

template<class Type>
bool operator==(const precompute_key<Type> &l, const precompute_key<Type> &r) {
    return l.value() == r.value();
}

namespace std {
    template<class Type>
    struct hash<precompute_key<Type>> {
        auto operator()(precompute_key<Type> const &arg) const {
            return arg.hash_value();
        }
    };
}

auto main() -> int {
    std::unordered_map<precompute_key<std::string>, std::string> m;

    m.emplace("k1", "Hello, World");

    return 0;
}
#包括
#包括
#包括
#包括
/*预计算密钥类型*/
模板
结构预计算密钥{
/*可以使用基础类型的任何构造函数构造*/
模板
预计算密钥(Args&…Args)
:value_(std::forward(args)…),hash_(std::hash()(value_)){}
运算符类型&(){返回值}
运算符类型const&()const{返回值}
自动哈希值()常量{返回哈希值}
自动值()常量{返回值}
自动值(){返回值}
私人:
类型值;
std::大小\u t散列\u;
};
模板
布尔运算符==(常量预计算键&l,常量预计算键&r){
返回l.value()==r.value();
}
名称空间标准{
模板
结构散列{
自动运算符()(预计算密钥常量和参数)常量{
返回arg.hash_值();
}
};
}
auto main()->int{
std::无序映射m;
m、 安置(“k1”,“你好,世界”);
返回0;
}

你的钥匙真的有那么慢吗(对于字符串来说可能如此!)。您是否分析过这是否真的是一个瓶颈?瓶颈在某种程度上存在于哈希中,但也存在于字符串的比较中。所需的最小工作量是进行散列,然后进行所需的比较。对于键长度均为线性的字符串。