我猜你在每次调用
NumGen时都需要创建一个
Random实例。为了让函数对于相同的参数返回相同的数字,你可以使用哈希函数。
我测试了一些东西,这段代码比重新创建
Random实例快了大约3倍。
static MD5 hasher = MD5.Create();
static byte[] outbuf;
static byte[] inbuf = new byte[12];
static float floatHash(uint x, uint y, uint z) {
inbuf[0]= (byte)(x >> 24);
inbuf[1]=(byte)(x >> 16);
inbuf[2]=(byte)(x >> 8);
inbuf[3]=(byte)(x);
inbuf[4]=(byte)(y >> 24);
inbuf[5]=(byte)(y >> 16);
inbuf[6]=(byte)(y >> 8);
inbuf[7]=(byte)(y);
inbuf[8]=(byte)(z >> 24);
inbuf[9]=(byte)(z >> 16);
inbuf[10]=(byte)(z >> 8);
inbuf[11]=(byte)(z);
outbuf = hasher.ComputeHash(inbuf);
return ((float)BitConverter.ToUInt64(outbuf, 0))/ulong.MaxValue;
}
使用一些RSA方法的另一种方法比new System.Random(seed)快约5倍:
static uint prime = 4294967291;
static uint ord = 4294967290;
static uint generator = 4294967279;
static uint sy;
static uint xs;
static uint xy;
static float getFloat(uint x, uint y, uint seed) {
sy = modPow(generator, (((ulong)seed) << 32) + (ulong)y, prime);
xs = modPow(generator, (((ulong)x) << 32) + (ulong)seed, prime);
xy = modPow(generator, (((ulong)sy) << 32) + (ulong)xy, prime);
return ((float)xy) / ord;
}
static ulong b;
static ulong ret;
static uint modPow(uint bb, ulong e, uint m) {
b = bb;
ret = 1;
while (e > 0) {
if (e % 2 == 1) {
ret = (ret * b) % m;
}
e = e >> 1;
b = (b * b) % m;
}
return (uint)ret;
}
我进行了一项测试,生成了100000个浮点数。我使用索引作为System.Random的种子,并将其作为floatHash的x参数(y和z都为0)。
System.Random:最小值:2.921559E-06 最大值:0.9999979 重复次数:0
floatHash MD5:最小值:7.011156E-06 最大值:0.9999931 重复次数:210(两个值返回了两次)
getFloat RSA:最小值:1.547858E-06 最大值:0.9999989 重复次数:190
System.Random
生成器。虽然它使用时间,但如果你用你的种子替换那个时间,甚至将两者结合起来,你就能得到你在这里描述的东西。 - undefined