python - 为什么 Python3.6 显示出比 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
3.7的结果timeit
仍然很糟糕,真的比 3.6 慢吗?
解决方案
你的计时方法有缺陷。在 6-7 秒内,现代操作系统不会让 Python 独占访问 CPU,其他事情也在发生,因为操作系统在进程之间切换,为正在写入的文件刷新磁盘缓冲区,执行预定的网络事件等。
您还生成了很多都加载到内存中的对象,因此 Python 必须向操作系统询问要分配的额外内存页面。这取决于您的计算机当时正在执行的其他内容,可以提供多快的内存。您似乎第二次运行 Python 3.6,因此很容易释放并重新分配给 Python 3.7 运行的内存仍可用于 3.6 运行,并且最近释放的内存更容易为操作系统重新分配。
接下来,您使用了一个相当不精确的挂钟计时器来计时您的表演。datetime.now()
对于想要知道当前时间的人来说很好,但对于测量性能来说并不好。对于后一项任务,Python 可以使用更好、更专业的时钟。Python 本身也有一个称为垃圾收集器的后台进程,它也需要一些时间来完成它的工作,这会影响 Python 执行你给它的任务的方式。
相反,您需要将 Python 必须在此处解决的不同问题分离到单独的测试中。在受控情况下运行这些单独的测试,使用准确的时钟,并尽可能多地禁用分心。多次运行这些测试,然后取平均时间(如果你只有一个可用的聚合)或多次重复的最佳时间。
Python为此提供了一个库,名为timeit
. 使用它只创建实例,而不是将它们全部存储在字典中。如前所述,内存分配取决于操作系统的时间,而不是 Python 的。确保不断重复您的测试;如果仅在您真的无法信任时间时-m timeit
运行测试,请减少在基准测试中完成的工作。
接下来,如果您的目标是在一般性能方面比较 Python 3.6 和 3.7,而不是特定的微基准,那么您将需要进行广泛的测试。从 3.x 到 3.x+1 版本,东西一直在变化。不要基于单个字符串连接或实例创建测试。并且知道 Python 开发人员已经完成了所有这些工作。请参阅https://speed.python.org/了解核心团队用于监控性能的一整套基准测试和计时,或参阅PyPerformance 套件了解另一个此类基准测试。
推荐阅读
- javascript - 内部的 https.request 等待获取不起作用
- .htaccess - Laravel 8 .htaccess 中的重写规则不执行任何操作
- c# - 实现一个接口方法,获取接口或基类的 IEnumerable 作为参数
- web-services - prestashop 1.7 使用 webservice 更新订单自定义字段
- sql - 有没有办法在 dateadd 中添加分数
- ms-word - Apache POI docx:HTML 作为 altChunk
- google-cloud-functions - 需要备份现有已部署的 firebase 功能
- php - 在变量中使用时调用数组上的成员函数 paginate()
- matlab - 如何使数据存储内存中的值全局化
- javascript - 如何制作可移动的模态?