【问题标题】:Calculating algorithm time计算算法时间
【发布时间】:2013-01-28 22:43:40
【问题描述】:

我有一个算法可以处理大约 2 的 4,500,000 次幂的极大数字。我使用 .NET 4 中的 BigInteger 类来处理这些数字。

该算法非常简单,因为它是一个单循环,可根据一些预定义的标准减少较大的初始数字。每次迭代,数字都会减少大约 10 个指数,因此 4,500,000 在下一次迭代中将变为 4,499,990。

我目前每秒进行 5.16 次迭代或每次迭代 0.193798 秒。基于此,算法的总时间应该是大约 22 小时才能将指数值降到 0。

问题是,随着数字的减少,在内存中处理数字所需的时间也会减少。另外,随着指数减少到 200,000 范围,每秒的迭代次数变得巨大,每次迭代的减少量也呈指数增长。

除了让算法运行一整天,有没有一种数学方法可以根据初始起始数和每秒迭代次数来计算需要多少时间?

这将非常有帮助,因为我可以快速衡量优化尝试的改进。

考虑以下伪代码:

double e = 4500000; // 4,500,000.
Random r = new Random();
while (e > 0)
{
    BigInteger b = BigInteger.Power(2, e);
    double log = BigInteger.Log(b, 10);
    e -= Math.Abs(log * r.Next(1, 10));
}

【问题讨论】:

  • e 增加了吗?
  • @thang:如果我从 200,000 的指数值开始,算法将只需要几秒钟的时间来处理。该算法当然要复杂得多,但上面的代码会产生相同的结果,因为每次迭代的大部分时间都由 BigInteger 构造函数消耗。所以你可以想象它会随着数量的减少而大大加快。
  • @CR41G14:我的错误。修复了代码。 e 在每次迭代中都会减少。
  • @thang:我不知道你是怎么得到这种印象的。请指出它,以便我可以更新问题。谢谢。
  • 您是否尝试过测量和插值作为 e 函数的每次迭代所需的时间?

标签: c# .net performance algorithm time


【解决方案1】:

由于您使用的是随机,因此无法估计未知的时间!

【讨论】:

  • 实际上 Random 仅用于代码示例中,以将每次迭代的减少限制在 1 到 10 之间。我很乐意使用这种近似水平。
  • 如果您说每次迭代都会因值而发生巨大变化,那么不,我认为这是不可能的,您唯一能做的就是获得每 1000 次迭代的经过时间并使用它作为客串。
【解决方案2】:

第一次重写

double log = BigInteger.Log(b, 10);

作为

double log = log(2)/log(10) * e; // approx 0.3 * e

然后您会注意到算法在 O(1) 次迭代后终止(每次迭代的终止几率约为 70%),您可能可以忽略除第一次迭代之外的所有成本。

对于初始指数 e,算法的总成本大约是 Math.Pow(2, e) 的 1 到 2 倍。对于 base=2,这是一个微不足道的位移,对于其他人,您需要平方和乘法

【讨论】:

  • 谢谢。我会试一试,看看它是否与实际时间足够接近。
猜你喜欢
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-11
  • 2021-08-25
相关资源
最近更新 更多