Pin*_*oyd 0 c++ performance templates c++11
我尝试了两件事:
class RandDouble{
public:
RandDouble(double const& min_inclusive, double const& max_exclusive):
mt_(std::random_device()),
dist_(min_inclusive,max_exclusive)
{}
~RandDouble(){}
double get(){ return dist_(mt_); }
private:
std::mt19937_64 mt_;
std::uniform_real_distribution<double> dist_;
};
class RandUnsignedInt{
public:
RandUnsignedInt(unsigned int const& min_inclusive, unsigned int const& max_inclusive):
mt_(std::random_device()),
dist_(min_inclusive,max_exclusive)
{}
~RandUnsignedInt(){}
unsigned int get(){ return dist_(mt_); }
private:
std::mt19937_64 mt_;
std::uniform_int_distribution<unsigned int> dist_;
};
Run Code Online (Sandbox Code Playgroud)
和
template<typename Type>
class Rand{
public:
Rand(Type const& min_inclusive, Type const& max_exclusive);/
~Rand();
Type get();
private:
std::mt19937_64 mt_;
std::uniform_real_distribution<double>* dist_double_;
std::uniform_int_distribution<unsigned int>* dist_u_int_;
};
template<typename Type>
Rand<Type>::~Rand(){
if(dist_double_){ delete dist_double_; }
if(dist_u_int_){ delete dist_u_int_; }
}
Run Code Online (Sandbox Code Playgroud)
与.cpp文件:
template<>
Rand<double>::Rand(double const& min_inclusive, double const& max_exclusive):
mt_(std::random_device()()),
dist_double_(new std::uniform_real_distribution<double>(min_inclusive,max_exclusive)),
dist_u_int_(NULL)
{}
template<>
Rand<unsigned int>::Rand(unsigned int const& min_inclusive, unsigned int const& max_exclusive):
mt_(std::random_device()()),
dist_double_(NULL),
dist_u_int_(new std::uniform_int_distribution<unsigned int>(min_inclusive,max_exclusive))
{}
template<>
double Rand<double>::get(){ return (*dist_double_)(mt_); }
template<>
unsigned int Rand<unsigned int>::get(){ return (*dist_u_int_)(mt_); }
Run Code Online (Sandbox Code Playgroud)
从实际的角度来看,模板解决方案与其他模板类更灵活,因为我可以做以下事情:
template<typename Type>
classs C{
/*some code*/
private:
Rand<Type> r;
};
Run Code Online (Sandbox Code Playgroud)
所以我喜欢模板解决方案.但是当我检查它需要调用Rand<double/unsigned int>::get()方法的时间时,我意识到它需要的时间比从RandDouble::get()或调用时间多两倍RandUnisignedint::get().
有一种方法可以保持模板方法的灵活性,调用方法与具有两个不同类的方法一样高效.
问题可能是通过使用指向分发类的指针获得的间接性.尝试直接使用没有指针的类,或者更好地做类似的事情
typename std::conditional<std::is_integral<Type>::value
, std::uniform_int_distribution<Type>
, std::uniform_real_distribution<Type> >::type _dist;
Run Code Online (Sandbox Code Playgroud)
为了选择您需要的分配类型.(这只是为了给你一个提示,类型检查肯定可以改进).
说明:上面的代码如下所示:std::conditional<(1),(2),(3)>就像类型的静态if语句一样.如果第一个字段中的检查(1)计算结果为true,则它将采用第二个字段中(2)的类型,否则它将在第三个字段中选择类型(3).
如果模板参数Type是整数类型,std::is_integral<Type>::value将评估为true.因此,您的分发类型std::uniform_int_distribution<Type>通常是期望的.
如果Type它不是整数类型(而是浮点类型,但是这里没有检查),而是std::uniform_real_distribution<Type>用于分布的类型.
示例(在此测试):
#include<random>
#include<iostream>
template<typename Type>
struct UniformDistribution
{
std::mt19937_64 mt_;
typename std::conditional<std::is_integral<Type>::value
, std::uniform_int_distribution<Type>
, std::uniform_real_distribution<Type> >::type dist_;
Type get()
{
return dist_(mt_);
}
};
int main()
{
//produces uniformly distributed integer number in [0, numeric_limist<int>::max()]
std::cout<<UniformDistribution<int>().get()<<std::endl;
//produces uniformly distributed double number in [0,1]
std::cout<<UniformDistribution<double>().get()<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
236 次 |
| 最近记录: |