计算对数算法的时间

时间:2012-08-13 17:03:07

标签: c# .net performance algorithm time

我需要计算算法在没有实际运行代码的情况下花费的大概时间。

我实际上无法让完整的算法运行,因为根据硬件需要数天或数周才能完成。该算法本质上是对数的。以下是算法的估计。当然,这里没有逻辑。

我们从[n]的力量开始,其中[n]是大数字。

int baseTwo = 2;
double log = 0D;
BigInteger number = 0;
double exponent = 5000000; // 5,000,000.

while (exponent > 0)
{
    number = BigInteger.Pow(baseTwo, (int) exponent); // [baseTwo]=2 raised to the power [exponent].
    number = this.ProcessNumber(number, baseTwo); // Returned number will be slightly smaller than what went in.
    exponent = BigInteger.Log(number, baseTwo); // The Base 2 Log to calculate the slightly decreased exponent (if exponent was 38762, then the result would be 38761.4234 for example).
}

private BigInteger ProcessNumber(BigInteger number)
{
    double rand = 0;
    BigInteger result = 0;

    rand = Random.Next(51, 100) / 100D; // Anywhere between 51% to 99%.
    result = number * rand; // [result] will always be less than [number] but more than half of [number].

    return (result);
}

由于指数向零迭代,每次迭代的时间自然从一次迭代减少到下一次迭代。

  • 考虑到我的机器上第一次和最后一次迭代的执行时间,有没有办法计算总时间?
  • 如果没有,我们可以为[指数]采取谨慎的范围说5,000,000,4,500,000,4,000,000等,并从那里计算?

2 个答案:

答案 0 :(得分:3)

即使您知道算法的限制性大O效率,第一次也是最后一次迭代都不会为您提供足够的信息,因为无法保证每次迭代的时间精确到达限制效率。例如,如果你的函数是大n的限制中的O(n ^ 2)(我知道它不是在这种情况下 - 但这仅仅是为了说明),而是实际代码的每一步的实际时间有点像1 * log(n)+ 10 ^ -6 * n + 10 ^ -24 * n ^ 2,你可能不会看到 n ^ 2在你选择的n范围内的行为在。所以你会在第一次和最后一次迭代中得到两个点,但无法知道如何在它们之间画线。

您可以按照建议定期对数据进行采样,然后将其导出以进行拟合和/或数值积分。但是,假设你只需知道大致的总时间(或许+/- 10%)就应该做足够的事情...... 伪代码:

totaltime = 0;
for i := 0 to 5 do
begin
  starttime = now;
  for j := 0 to 10 do
    run algorithm(i*10^6+j)
  endtime = now;
  totaltime := totaltime + 10^5*(endtime - starttime);
  writeln('10 iterations near ', i*10^6, ' takes ', endtime - starttime, ' seconds');
end;
writeln('approximate time for complete algorithm to run is', totaltime);

..并在比我写这篇文章更短的时间内得到答案。

答案 1 :(得分:1)

我建议你的算法很小但输入量增加,并做一个图表。

图表上的曲线可能会突然发生变化,但它们可能仍然比许多类似的背包计算更好。