下面是一个简单的流程,分别用C#
和Python
编写(如果你对流程感兴趣,这是Project Euler第5题的解决方案) ).
我的问题是,下面的 C#
代码迭代只需要 9 秒,而完成 Python
代码需要 283 秒(准确地说,在 Python 3.4 上是 283 秒.3 - Python 2.7.9 - 32 位上的 64 位和 329 秒)。
到目前为止,我已经在 C#
和 Python
中编写了类似的流程,并且执行时间差异相当。然而,这一次,耗时之间存在极大差异。
我认为,这种差异的一部分来自于 python 语言的灵活变量类型(我怀疑,python 将一部分变量转换为 double),但这仍然很难解释。
我做错了什么?
我的系统:Windows-7 64 位,
C# - VS Express 2012(9 秒)
Python 3.4.3 64 位(283 秒)
Python 2.7.9 32 位(329 秒)
c-升码:
using System;
namespace bug_vcs {
class Program {
public static void Main(string[] args) {
DateTime t0 = DateTime.Now;
int maxNumber = 20;
bool found = false;
long start = maxNumber;
while (!found) {
found = true;
int i = 2;
while ((i < maxNumber + 1) && found) {
if (start % i != 0) {
found = false;
}
i++;
}
start++;
}
Console.WriteLine("{0:d}", start - 1);
Console.WriteLine("time elapsed = {0:f} sec.", (DateTime.Now - t0).Seconds);
Console.ReadLine();
}
}
}
和python代码:
from datetime import datetime
t0 = datetime.now()
max_number = 20
found = False
start = max_number
while not found:
found = True
i = 2
while ((i < max_number + 1) and found):
if (start % i) != 0:
found = False
i += 1
start += 1
print("number {0:d}\n".format(start - 1))
print("time elapsed = {0:f} sec.\n".format((datetime.now() - t0).seconds))
最佳答案
答案很简单,Python 处理所有对象,它没有JIT。默认。因此,与其通过修改堆栈上的几个字节并优化代码的热点部分(即迭代)来提高效率,Python 会与表示数字的丰富对象一起运行,并且没有即时优化。
如果您在具有 JIT 的 Python 变体(例如 PyPy)中尝试过此操作,我保证您会看到巨大的差异。
一般提示是避免使用标准 Python 进行计算量大的操作(尤其是当后端服务来自多个客户端的请求时)。 Java、C#、JavaScript等,加上JIT,效率无可比拟。
顺便说一下,如果您想以更 Pythonic 的方式编写您的示例,您可以这样做:
from datetime import datetime
start_time = datetime.now()
max_number = 20
x = max_number
while True:
i = 2
while i <= max_number:
if x % i: break
i += 1
else:
# x was not divisible by 2...20
break
x += 1
print('number: %d' % x)
print('time elapsed: %d seconds' % (datetime.now() - start_time).seconds)
上面的代码对我来说只用了 90 秒。它更快的原因依赖于看似愚蠢的事情,比如 x
比 start
短,我没有经常分配变量,而且我依赖 Python 自己的控制结构而不是变量检查来跳入/跳出循环。
关于c# - 为什么我在 C# 中的计算比 Python 快得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29903320/