昨天我解决了一个考试问题,当发现一些非常有趣的事情时(至少对我而言)。该程序用于阶乘(非常大),结果是数字末尾有多少个零(在某些情况下2500
为零。)。所以我尽我所能,但发现当输入100 000
之类的数字时,输出结果需要1;30 - 1;33min
。我认为这是因为我的CPU(它不是很快)。我已经将.exe发送给我的一些朋友来尝试了,因为当我们谈论性能时他们有非常好的PC - 完全相同的结果(1;33min
)。
我的问题是为什么解决任务的时间是一样的。 我知道有更好的方法来编写我的核心所以它不会花这么长时间,但这对我来说非常重要,因为我作为初学者程序员可以理解。 所以这是我的代码:
static void Main()
{
int num = int.Parse(Console.ReadLine()),
zeroCounter = 0;
BigInteger fact = 1;
var startTime = DateTime.Now;
Console.WriteLine();
for (int i = 1; i <= num; i++)
{
fact *= i;
Console.Write("\r{0}", DateTime.Now - startTime);
}
BigInteger factTarget = fact;
while (factTarget % 10 == 0)
{
factTarget /= 10;
zeroCounter++;
Console.Write("\r{0}", DateTime.Now - startTime);
}
Console.WriteLine();
Console.WriteLine("Result is number with {0} zeros.", zeroCounter);
Console.WriteLine();
Console.WriteLine("Finished for: {0}", DateTime.Now - startTime);
Console.WriteLine();
Console.WriteLine("\nPres any key to exit...");
Console.ReadKey();
}
我很抱歉如果这是一个错误的地方,我会尽力找到我要找的东西。
答案 0 :(得分:5)
我立即注意到你的代码就是你在计算循环中包含Console.WriteLine()
语句。
事实上,即使在理想条件下,计算机处理的I / O也比计算慢得多。我不会说Windows控制台窗口是特定类型I / O的特别有效的实现。此外,I / O往往较少依赖于机器之间的CPU和内存差异。
换句话说,我很可能主要测量I / O吞吐量而不是计算吞吐量,因此在机器之间看到一致的结果并不奇怪。
为了它的价值,当我在笔记本电脑上运行你的例子时,如果我禁用输出,我可以在大约一分钟内完成计算。如果我按原样使用代码,我会更接近你的1:30时间。
修改强>
我也推荐Hans Passant的答案。内存I / O仍然是I / O,正如我上面所描述的那样,机器之间的变化远不如CPU速度。我希望上面的通用描述可以提供差异所在的想法(如果没有访问相关的每台机器,那么<em>肯定没有任何方法可以确定 / em>原因是什么),但Hans的回答提供了一些关于内存I / O问题的非常好的细节,非常值得一读。
答案 1 :(得分:3)
现在时间是00:01:23.5856140
此程序的速度取决于机器中RAM的带宽。它是一个设计常数,与处理器的速度无关。 RAM在这里起作用,因为阶乘中的数字非常多,它们不再适合CPU缓存。并且BigInteger乘法的内存访问模式非常不友好,所有数字都需要乘以一个数字。
我的笔记本电脑上的程序需要57秒,我知道它有PC3-12800内存。其峰值传输速率为12800 MB /秒,给出或采用CAS延迟(我不了解我的)。因此,我们可以计算您和您朋友的机器的RAM速度:
1:23 = 83秒,57/83 x 12800 = 8790 MB /秒。
对于PC3-8500,这是pretty close match。在白盒机器中非常普遍的普通RAM速度,这种类似于戴尔这样的供应商。你朋友的快速电脑有点烤面包机,轻轻地给他打电话:)
Fwiw,为什么高度受欢迎的帖子对速度没有多大影响也可以使用解释。程序使用的控制台窗口由另一个进程拥有。 Conhost.exe,您可以在Taskman.exe的“进程”选项卡中看到它。它负责滚动和绘制窗口,在引擎盖下,程序使用process-interop告诉它更新窗口。
当你的程序正在运行时,在另一个线程上发生这种情况,所以你的程序只有当它发送Conhost.exe时才会陷入困境,发送的更新速度超过它能处理的速度。因此,在您的计划开始时,您仍然很快,并将陷入困境。但是当数字的数量开始变大并且你的乘法开始变慢时就不会这样。总体而言,经济放缓并不是那么好。
答案 2 :(得分:0)
内核总线或处理器具有固定大小的内部总线,用于存储数据。 RAM的速度比处理器慢10-1000倍。还有一种称为Cache内存的东西,但缓存内存的大小很小。那么,你的电脑中存在如此大的RAM,它仍然会很慢而且需要时间。当它达到高数字时,数字需要时间来读取和写入内存。
每次在屏幕上写字都需要一段时间。