为什么 Python3.6 显示出比 3.7 更好的结果?

Why Python3.6 showing better results than 3.7?

我有下面的代码(没用,只是为了性能测试)

class A:
    def __init__(self, i):
        self.i = i

start = datetime.now()
foo = {}
for i in range(10000000):
    foo[i] = A(i)

print('\nSpent: [ {} ] seconds!'.format((datetime.now()-start).total_seconds()))

事情是,当我 运行 它与 Python3.7 我得到以下结果

Spent: [ 7.644764 ] seconds!

但是当我 运行 它与 Python3.6

Spent: [ 6.521555 ] seconds!

所以问题是,我是不是误解了什么,或者旧的 python 更快,我应该使用旧的?

UPD:正如评论中所建议的,我使用了 timeit 模块,这里是结果

python3.7 -m timeit '"-".join(str(n) for n in range(2000000))'
1 loop, best of 5: 499 msec per loop

python3.6 -m timeit '"-".join(str(n) for n in range(2000000))'
10 loops, best of 3: 405 msec per loop

timeit 的结果对于 3.7 来说仍然很糟糕,它真的比 3.6 慢吗?

你的计时方法有问题。在 6-7 秒内,现代 OS 不会授予 Python 对 CPU 的独占访问权限,其他事情也在发生,因为 OS 在进程之间切换,刷新磁盘正在写入的文件的缓冲区,执行计划的网络事件等

您还生成了相当多的对象,这些对象都被加载到内存中,因此 Python 必须向 OS 请求分配额外的内存页面。这取决于您的计算机当时正在执行的其他操作,可以提供多快的内存。看来你 运行 Python 3.6 秒,所以很容易释放内存并重新分配给 Python 3.7 运行 仍然可用于 3.6 运行,最近释放的内存更容易重新分配给 OS。

接下来,您使用了一个相当不精确的挂钟计时器来为您的表演计时。 datetime.now() 对于想要知道当前时间的人来说很好,但对于衡量性能来说并不好。对于后一项任务,Python 可以使用更好、更专业的时钟。 Python 本身也有一个名为 垃圾收集器 的后台进程,它也需要一些时间来完成它的工作,影响 Python 如何执行你的任务给了。

相反,您需要将 Python 必须在此处解决的不同问题分离到单独的测试中。 运行 那些在受控环境下进行的单独测试,具有准确的时钟,并尽可能多地禁用干扰。 运行 这些测试 很多很多次 然后取平均时间(如果你只有一个可用的总和)或多次重复的最佳时间。

Python 有一个库,叫做 timeit。使用它来 创建实例,而不是将它们全部存储在字典中。如前所述,内存分配受制于 OS 的计时,而不是 Python 的计时。确保不断重复你的测试;如果 -m timeit 运行 只测试 一次 你真的不能相信时间,减少基准测试中完成的工作。

下一步,如果您的目标是在 一般性能术语 上比较 Python 3.6 与 3.7,而不是特定的微基准,那么您需要广泛的 运行ge 的测试。从 3.x 到 3.x+1 版本,内容一直在变化。不要将任何内容基于单个字符串连接或实例创建测试。并且知道 Python 开发人员 已经 完成了所有这些工作。有关另一个此类基准,请参阅 https://speed.python.org/ for a full suite of benchmarks and timings that the core team uses to monitor performance, or see the PyPerformance suite