为什么Python3.6的结果比3.7好?

Mad*_*di7 -1 python performance performance-testing python-3.x

我有以下代码(它无用,仅用于性能测试)

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()))
Run Code Online (Sandbox Code Playgroud)

事实是,当我用Python3.7运行它时,得到以下结果

Spent: [ 7.644764 ] seconds!
Run Code Online (Sandbox Code Playgroud)

但是当我用Python3.6运行它时

Spent: [ 6.521555 ] seconds!
Run Code Online (Sandbox Code Playgroud)

所以问题是,我是否会误解某些东西,还是旧版本的python速度更快,应该使用旧版本的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
Run Code Online (Sandbox Code Playgroud)

的结果timeit对于3.7来说仍然不好,真的比3.6慢吗?

Mar*_*ers 7

您的计时方法有缺陷。在6到7秒钟内,现代操作系统不会为Python提供对CPU的独占访问权,其他事情也在发生,因为操作系统在进程之间切换,刷新磁盘缓冲区以写入文件,执行计划的网络事件等。

您还会生成很多都已加载到内存中的对象,因此Python必须向OS询问要分配的其他内存页面。这取决于您的计算机在当时还能执行多快的速度。看来您运行了Python 3.6秒,因此很可能是释放的内存和重新分配给Python 3.7运行的内存仍可用于3.6运行,并且最近释放的内存更容易为OS重新分配。

接下来,您使用了一个不太精确的挂钟计时器来计时您的演奏。datetime.now()对于想知道当前时间的人来说是很好的选择,而对于衡量性能却不是很好。对于后者,Python有更好,更专业的时钟可用。Python本身也有一个称为垃圾收集器的后台进程,该进程还将希望花一些时间来完成其工作,从而影响Python执行给它的任务的方式。

相反,您需要将Python必须在此处解决的不同问题分开进行单独的测试。在受控的情况下,使用准确的时钟并在尽可能多的干扰下禁用它们,来运行这些单独的测试。多次运行这些测试然后花费平均时间(如果您只有可用的汇总)或多次重复的最佳时间。

Python为此提供了一个库timeit。使用它创建实例,也不将其全部存储在字典中。如前所述,内存分配取决于操作系统的时间,而不是Python的时间。确保继续重复测试;如果-m timeit您真的不敢相信计时的情况下进行测试,请减少基准测试中完成的工作。

接下来,如果您的目标是按照常规性能而非特定的微基准来比较Python 3.6与3.7 ,那么您将需要进行广泛的测试。Stuff始终从3.x更改为3.x + 1版本。不要以单个字符串连接或实例创建测试为基础。并且知道Python开发人员已经完成了所有工作。请参阅https://speed.python.org/以获取核心团队用来监视性能的全套基准测试和计时,或参阅PyPerformance套件以获取另一种此类基准。