快速,快速随机整数生成器
Fast, Fast random integer generator
有多种算法,如XorShift,可以非常快速地生成满足一般用途的随机数。不幸的是,我需要生成一个从 [0 到 10] 的随机整数,在我的代码中使用 rand()
函数会导致 ~23% 的速度变慢。
问题:生成从 [0 到 10] 的整数的最快方法是什么?
编辑:基于布兰登评论的信息:
~23%的减速假设你已经把它比作某事。你把它和什么比较了?
> 我正在做 rand() % 10> 5。
也:
-
在循环外使用
srand(time(0));
什么都不做。 -
隔离
rand() % 10
为 ~19%,因此比较对性能的影响不大。
Xorshift是一个很棒的算法。使用它来生成一个充满随机位的缓冲区。仅仅因为它一次填充缓冲区 32 位,就没有理由必须一次从缓冲区中读取 32 位。既然你想要速度,你就想避免除法(和模组)。唯一的方法是通过拒绝抽样(也是获得完全无偏数字的唯一方法)。
由于您只需要 11 个值(0 到 10),因此每个样本只需要 4 位。每 16 个样本中您将拒绝 5 个,但由于每 32 位有 8 个样本,因此每次 Xorshift 迭代平均有 5.5 个输出值。
因此,从 Xorshift 填充一个大缓冲区,然后将该缓冲区转换为 (0 到 10) 值,如下所示:
for (int b = 0; b < sizeof inbuf; b += 1) {
uint8_t v = ((uint8_t *)inbuf)[b];
if ((v & 0x0F) < 10) { *outbuf++ = v & 0x0F; }
if (((v >> 4) & 0x0F) < 10) { *outbuf++ = ((v >> 4) & 0x0F; }
}
outbuf
一个字节数组的大小是inbuf
的两倍,它将是大约 11/16 满的。根据需要重新填充两个缓冲区。
您是否尝试过标准的 mersenne twister 实现?以下示例来自 Microsoft 的联机帮助:
#include <random>
#include <iostream>
using namespace std;
int main()
{
random_device rd; // non-deterministic generator
mt19937 gen(rd()); // to seed mersenne twister.
uniform_int_distribution<> dist(0,10); // distribute results between 1 and 10 inclusive.
for (int i = 0; i < 5; ++i) {
cout << dist(gen) << " "; // pass the generator to the distribution.
}
cout << endl;
}
上次我使用了松本诚的实现,它比rand()
快得多。我没有对它进行基准测试,但我猜标准实现也更快。
SSE2还特别支持随机数生成,可能更快:https://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor
- 生成线性随机整数C++
- 如何生成 0 到 0x7FFFFFFF 的随机整数?
- 生成随机整数
- C++:随机数列表:x 个随机整数
- C++带有权重的随机非重复整数
- 列出小于 10 的不同随机整数
- 在 c++ 中生成随机整数
- C++随机函数给出的相同整数是输出的两倍
- 取消随机排列整数/字符数组
- 随机选择 2 个不在范围内的整数
- 我将如何防止整数在随机发生器中多次生成
- C++ 通过 range for 循环将整数输入到矢量中;随机 0
- 随机整数仍在生成低于或高于范围的数字?
- C++,为什么我不能使用两个默认随机引擎生成独立的随机整数样本
- 在 C++ 中使用 10 个随机整数的数组进行气泡排序不起作用
- C++ 如何生成 10,000 个 UNIQUE 随机整数以存储在 BST 中?
- 如何将唯一的随机整数插入链表中
- 伪随机整数
- 生成伪随机16位整数
- 使用boost::random库获取整数随机值而不是实数