将C++向量初始化为随机值...快速

Fla*_*res 12 c++ random optimization vector

嘿,我喜欢尽可能快地制作它,因为它在我正在编写的程序中被称为A LOT,所以有没有更快的方法将C++向量初始化为随机值:

double range;//set to the range of a particular function i want to evaluate.
std::vector<double> x(30, 0.0);
for (int i=0;i<x.size();i++) {
    x.at(i) = (rand()/(double)RAND_MAX)*range;
}
Run Code Online (Sandbox Code Playgroud)

编辑:修复了x的初始化程序.

Jer*_*fin 17

现在,这应该非常快,因为循环不会执行.

就个人而言,我可能会使用这样的东西:

struct gen_rand { 
    double range;
public:
    gen_rand(double r=1.0) : range(r) {}
    double operator()() { 
        return (rand()/(double)RAND_MAX) * range;
    }
};

std::vector<double> x(num_items);
std::generate_n(x.begin(), num_items, gen_rand());
Run Code Online (Sandbox Code Playgroud)

编辑:这纯粹是微观优化,根本没有任何区别,但您可以考虑重新安排计算,以获得类似:

struct gen_rand { 
    double factor;
public:
    gen_rand(double r=1.0) : factor(range/RAND_MAX) {}
    double operator()() { 
        return rand() * factor;
    }
};
Run Code Online (Sandbox Code Playgroud)

当然,编译器很有可能已经做到这一点(或类似的东西),但无论如何都不会受到影响(尽管它真的只能帮助优化关闭).

Edit2:"sbi"(通常就是这种情况)是对的:你最初可以通过保留空间获得一点,然后使用插入迭代器将数据放到位:

std::vector<double> x;
x.reserve(num_items);
std::generate_n(std::back_inserter(x), num_items, gen_rand());
Run Code Online (Sandbox Code Playgroud)

和以前一样,我们正在进行这样的微观优化,我完全不确定我是否真的希望看到差异.特别是,由于这一切都是通过模板完成的,因此大多数(如果不是全部)代码都是内联生成的.在这种情况下,优化器可能会注意到初始数据都被覆盖,并跳过初始化.

然而,最终,几乎唯一真正可能产生重大影响的部分就是摆脱它.at(i).其他人可能,但随着优化的开启,我真的不希望他们这样做.

  • 这仍然使用"0.0"值预先初始化向量,然后将其覆盖.`reserve()`和插入迭代器不会消除它吗? (5认同)

lea*_*vst 12

我一直在使用Jerry Coffin的仿函数方法,但随着C++ 11的到来,我们有了很多很酷的新随机数功能.要使用随机float值填充数组,我们现在可以执行以下操作...

const size_t elements = 300;
std::vector<float> y(elements);    
std::uniform_real_distribution<float> distribution(0.0f, 2.0f); //Values between 0 and 2
std::mt19937 engine; // Mersenne twister MT19937
auto generator = std::bind(distribution, engine);
std::generate_n(y.begin(), elements, generator); 
Run Code Online (Sandbox Code Playgroud)

有关更多引擎和发行版,请参阅Wikipedia的相关部分


Mic*_*yan 5

是的,而x.at(i)确实检查边界,x [i]不这样做.此外,您的代码不正确,因为您未能提前指定x的大小.您需要使用std::vector<double> x(n),其中n是您要使用的元素数量; 否则,你的循环永远不会执行.

或者,您可能希望创建一个自定义迭代器来生成随机值并使用迭代器填充它; 因为std :: vector构造函数会初始化它的元素,所以如果你有一个生成随机值的自定义迭代器类,你可以消除对项目的传递.

在实现自己的迭代器方面,这是我未经测试的代码:

 class random_iterator
 {
     public:
         typedef std::input_iterator_tag iterator_category;
         typedef double value_type;
         typedef int difference_type;
         typedef double* pointer;
         typedef double& reference;

         random_iterator() : _range(1.0), _count(0) {}
         random_iterator(double range, int count) : 
                                         _range(range), _count(count) {}
         random_iterator(const random_iterator& o) : 
                                         _range(o._range), _count(o._count) {}
         ~random_iterator(){}

         double operator*()const{ return ((rand()/(double)RAND_MAX) * _range); }
         int operator-(const random_iterator& o)const{ return o._count-_count; }
         random_iterator& operator++(){ _count--; return *this; }
         random_iterator operator++(int){ random_iterator cpy(*this); _count--; return cpy; }
         bool operator==(const random_iterator& o)const{ return _count==o._count; }
         bool operator!=(const random_iterator& o)const{ return _count!=o._count; }

     private:
         double _range;
         int _count;
 };
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,应该可以使用:

std::vector<double> x(random_iterator(range,number),random_iterator());
Run Code Online (Sandbox Code Playgroud)

也就是说,给出的其他解决方案的生成代码更简单,坦率地说,我只是明确地填充向量而不诉诸任何像这样的花哨......但是考虑它有点酷.