我有一段代码用于确定某个事件是否应该发生。代码看起来像这样。
If (Date.Now.Ticks Mod 100) < 4 Then
Return True
Else
Return False
End If
这里的想法是,这个事件应该发生在100次中的4次,或4%。但是,在生产中,实际百分比范围为10%至60%。该应用程序托管在两个负载均衡的Win2k3服务器上。
任何建议都会有所帮助。
基思
答案 0 :(得分:3)
你为什么不用这个:
Dim r As New Random(System.DateTime.Now.Millisecond)
Return r.Next(0, 100)
答案 1 :(得分:2)
你获得这种行为的原因是你没有要求4%的时间给你一个真值,你要求任何时候Ticks模数的数量100小于4.
给定一个统一的随机数生成器,如System.Random:
Dim random As New Random()
Return random.NextDouble() < 0.04
使用Random.NextDouble,您将有相同的概率选择0.0到1.0之间的任何数字。因此,只要随机双精度小于0.04,我就可以通过返回真值来要求真正的4%。
答案 2 :(得分:1)
查看DateTime.Now.Ticks的结果。在我的盒子上(这是一个Vista盒子 - 操作系统几乎肯定在这里很重要)取样5秒钟并获得所有不同的值, all 滴答计数以“91”结束。这个代码如下。
虽然服务器上显然不是 坏,但计时器粒度肯定会产生重大影响。使用随机数生成器肯定是更好的选择。请注意,您应该为每个线程创建一个Random
或可能一个实例 - 并且Random
不是线程安全的。为简单起见,您可能希望在StaticRandom中使用我的MiscUtil课程。
这是嘀嗒测试代码:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
public class Test
{
static void Main()
{
foreach(long tick in GetTicks().Distinct())
{
Console.WriteLine(tick);
}
}
static IEnumerable<long> GetTicks()
{
DateTime end = DateTime.Now.AddSeconds(5);
DateTime now;
while ((now = DateTime.Now) < end)
{
yield return now.Ticks;
}
}
}
答案 3 :(得分:1)
首先,返回的滴答数可以通过从它取出的任何系统计时器的常数因子来缩放,这样它就不会命中每个整数,并且将它取为mod 100将不会给出0中的每个数字到99,概率相等。
其次,如果您的代码是事件驱动的,系统将确定它何时被激活;这个激活时间可能趋向于固定倍数的刻度。此外,激活和执行代码之间的运行时间往往相似。因此,根据计算机上发生的其他情况,刻度数将是半可预测的。
结果是,滴答数量高度依赖于系统;你想用一个实际的随机数发生器得到你的随机数......
答案 4 :(得分:0)
100次中有4次?所以你想要“Ticks mod 25 == 0”?另外,我不是VB程序员,但你能不能摆脱所有“If - Else”和“Return(Date.Now.Ticks mod 25)== 0”吗?
答案 5 :(得分:0)
随机性的本质是你得到随机结果。如果您的实际百分比在10%到60%之间运行,那么您的代码可能正常运行,但您的样本量可能太小而无法收敛。
答案 6 :(得分:0)
使用truly random number generator比依赖时间函数要好得多。