我在一个项目中用C实现了一个hashmap,并使用随机插入来测试它。我注意到Linux上的rand()
似乎比Mac上重复数字的频率要高得多。rand_max
在两个平台上都是2147483647/0x7fffffff
。我将它简化为一个测试程序,它创建一个字节数组rand_max+1
-long,生成rand_max
随机数,注意每个随机数是否重复,并从列表中检查。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main() {
size_t size = ((size_t)RAND_MAX) + 1;
char *randoms = calloc(size, sizeof(char));
int dups = 0;
srand(time(0));
for (int i = 0; i < RAND_MAX; i++) {
int r = rand();
if (randoms[r]) {
// printf("duplicate at %d\n", r);
dups++;
}
randoms[r] = 1;
}
printf("duplicates: %d\n", dups);
}
Linux始终如一地生成了大约7.9亿个副本。Mac始终如一地只生成一个,因此它几乎不重复地遍历它可以生成的每个随机数。谁能给我解释一下这是怎么工作的吗?我分不清与man
页面有什么不同,分不清每个人在使用哪一个RNG,在网上也找不到任何东西。谢谢!
虽然一开始听起来好像macOSrand()
在不重复任何数字方面更好,但我们应该注意到,随着生成的数字数量的增加,预计会出现大量的重复(实际上,大约有7.9亿个,或者(231-1)/e)。同样地,按顺序迭代数字也不会产生重复,但不会被认为是非常随机的。因此,在本测试中,Linux的rand()
实现与真正的随机源无法区分,而macOS的rand()
则不然。
第一眼看上去令人惊讶的另一件事是macOSrand()
如何能够很好地避免重复。查看其源代码,我们发现实现如下:
/*
* Compute x = (7^5 * x) mod (2^31 - 1)
* without overflowing 31 bits:
* (2^31 - 1) = 127773 * (7^5) + 2836
* From "Random number generators: good ones are hard to find",
* Park and Miller, Communications of the ACM, vol. 31, no. 10,
* October 1988, p. 1195.
*/
long hi, lo, x;
/* Can't be initialized with 0, so use another value. */
if (*ctx == 0)
*ctx = 123459876;
hi = *ctx / 127773;
lo = *ctx % 127773;
x = 16807 * lo - 2836 * hi;
if (x < 0)
x += 0x7fffffff;
return ((*ctx = x) % ((unsigned long) RAND_MAX + 1));
这确实会导致在序列再次重复之前,在1和rand_max
之间的所有数字(包括1和rand_max
之间)恰好出现一次。因为下一个状态是基于乘法的,所以这个状态永远不可能是零(或者以后所有的状态也都是零)。因此,你看到的重复数是第一个,而零是永远不会返回的那个。
至少在macOS(或OS X)存在的时候,苹果就一直在他们的文档和示例中推广使用更好的随机数生成器,所以rand()
的质量可能并不重要,他们只是坚持使用一种最简单的伪随机数生成器。(正如您所注意到的,他们的rand()
甚至被注释为建议改用arc4random()
。)
与此相关的一点是,我能找到的最简单的伪随机数生成器是xorshift*,它能在这个(和许多其他)随机性测试中产生良好的结果:
uint64_t x = *ctx;
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
*ctx = x;
return (x * 0x2545F4914F6CDD1DUL) >> 33;
这个实现在您的测试中几乎精确地产生了7.9亿个重复。
我观察到库函数,当它在循环中被调用一次时,它几乎总是产生正数。
因此,从Hadoop教程网站(http://Hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapreducetutorial.html#source_code)上,我了解了如何使用map reduce方法实现单词计数,并且输出的单词都是出现频率的。 我想做的是只有输出是最高频率
我正在一个网络接口上使用1台主机(192.168.0.1)和7台带有3个VM(192.168.0.2到192.168.00.4)的从机执行JMeter远程测试,其他4个VM(92.168.0.5到192.168.8.8)位于不同的网络接口上。 我的JMeter脚本位于主机器 - 192.168.0.1 我尝试使用以下命令执行测试 然而,测试从未开始。屏幕刚刚挂起,15分钟后我不得不停止测试。我只使
我们的应用程序使用Amazon RDS Aurora的reader和writer实例。AWS仪表板显示副本延迟持续约为20ms。然而,我们在阅读器上看到的旧结果是在主机上提交后90ms以上,在某些情况下至少高达170ms。 当执行CRUD操作时,我们的应用程序提交数据,然后向客户端发出HTTP重定向以加载新数据。重定向时的网络周转记录在客户端上,通常至少为90ms。我们正在记录应用服务器上的提交时
我正在学习python,我想创建一些代码,这些代码将获取列表列表,检查每一行对于给定的索引号是否有特定的值,如果有,则删除整行。现在我直觉地决定使用删除行,但是当我打印出带有删除值的列表时,我得到了相同的列表。我添加了一个计数器来检查是否有任何行具有要删除的值,并且它们确实存在。以下代码说明了我遇到的问题: 输出 如果不删除此处的元素,del的功能是什么?