【问题标题】:Efficiency of Random.Next() vs Random.NextDouble()Random.Next() 与 Random.NextDouble() 的效率
【发布时间】:2018-03-15 13:41:23
【问题描述】:

我需要在 C# 中生成一个介于 0 和 1 之间的随机数。它不需要比一个小数位更准确,但如果是的话也不是问题。

我可以选择Random.Next(0, 10) / 10.0Random.NextDouble()

我找不到任何关于这两种方法时间复杂度的具体信息。我认为Random.Next() 会像在 Java 中一样高效,但是添加除法(其复杂性取决于 C# 使用的方法)会使事情复杂化。

是否有可能纯粹从理论上找出哪个更有效?我意识到我可以通过一系列测试来计时,但想了解为什么其中一个比另一个更复杂。

【问题讨论】:

  • 理论并不像实际结果那么重要。因此,如果您好奇,请使用benchmarking library 来实际测量性能差异。
  • 1.运行基准测试以检查 2。您可以在此处阅读两种实现的源代码:referencesource.microsoft.com/#mscorlib/system/…
  • 我认为您在这里过于强调效率。
  • 您只需要 10 个不同的值,可以轻松放入数组中。不一定更快,你必须测量。
  • 测试:不,比 NextDouble() 慢约 18%。这不必优化。

标签: c# performance random time-complexity


【解决方案1】:

implmenentation source codeNextDouble()会更有效率。

NextDouble() 只是调用Sample() 方法:

public virtual double NextDouble() {
    return Sample();
}

Next(maxValue)对maxvalue进行比较,调用Sample(),将值乘以maxvalue,转换为int并返回:

public virtual int Next(int maxValue) {
    if (maxValue<0) {
        throw new ArgumentOutOfRangeException("maxValue", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", "maxValue"));
    }
    Contract.EndContractBlock();
    return (int)(Sample()*maxValue);
}

因此,如您所见,Next(maxValue)NextDouble() 做相同的工作,然后做更多工作,因此NextDouble() 返回介于 0 和 1 之间的数字会更有效。

对于 Mono 用户,您可以在此处查看 NextDouble()Next(maxValue) 实现。 Mono 的做法略有不同,但基本上与官方实现的步骤相同。

正如 Zoran 所说,您需要生成大量随机数才能发现差异。

【讨论】:

    【解决方案2】:

    无论哪种方式,您都可以每秒生成数百万甚至数十亿个随机数。你真的需要那么多吗?

    在更具体的层面上,两种变体都有时间复杂度O(1),这意味着您可以测量两种方法之间的时间差,就是这样。

    Random generator = new Random();
    
    int count = 1_000_000;
    Stopwatch sw = new Stopwatch();
    sw.Start();
    double res;
    for (int i = 0; i < count; i++)
        res = generator.Next(0, 10) / 10.0;
    sw.Stop();
    
    Stopwatch sw1 = new Stopwatch();
    sw1.Start();
    for (int i = 0; i < count; i++)
        res = generator.NextDouble();
    sw1.Stop();
    
    Console.WriteLine($"{sw.ElapsedMilliseconds} - {sw1.ElapsedMilliseconds}");
    

    此代码在我的计算机上打印 44 毫秒:29 毫秒。再说一次 - 我不认为你应该优化一个需要 44 毫秒执行一百万次的操作。

    如果每次执行 15 纳秒仍然有区别,那么第二种方法要快一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 2011-07-05
      相关资源
      最近更新 更多