简体   繁体   English

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

[英]Why Python3.6 showing better results than 3.7?

I have the following code (Its useless, just for performance testing) 我有以下代码(它无用,仅用于性能测试)

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()))

The thing is, that when I run it with Python3.7 I get the following results 事实是,当我用Python3.7运行它时,得到以下结果

Spent: [ 7.644764 ] seconds!

But when I run it with Python3.6 但是当我用Python3.6运行它时

Spent: [ 6.521555 ] seconds!

So the question is, do I misunderstand something or the older python is faster and I should use the old one? 所以问题是,我是否会误解某些东西,还是旧版本的python速度更快,应该使用旧版本的python?

UPD: As suggested in the comments, I've used timeit module, here the results 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

The results with timeit are still bad for 3.7, is it really slower than 3.6 ? timeit的结果对于3.7来说仍然是不好的,真的比3.6慢吗?

Your timing method is flawed. 您的计时方法有缺陷。 Across 6-7 seconds a modern OS won't give Python exclusive access to the CPU, other things are happening too, as the OS switches between processes, flushes disk buffers for files being written, executes scheduled network events, etc. 在6到7秒钟内,现代操作系统不会为Python提供对CPU的独占访问权,其他事情也在发生,因为操作系统在进程之间切换,刷新磁盘缓冲区以写入文件,执行计划的网络事件等。

You also generate quite a lot of objects that are all loaded into memory, so Python has to ask the OS for additional memory pages to be allocated. 您还会生成很多都已加载到内存中的对象,因此Python必须向OS询问要分配的其他内存页面。 It depends on what else your computer was executing at the time how fast that memory can be given. 这取决于您的计算机在当时还能执行多快的速度。 It appears that you ran Python 3.6 second, so it could easily be that the memory freed and re-allocated to the Python 3.7 run is still available for the 3.6 run, and recently released memory is much easier to reallocate for the OS. 看来您运行了Python 3.6秒,因此很可能是释放的内存和重新分配给Python 3.7运行的内存仍可用于3.6运行,并且最近释放的内存更容易为OS重新分配。

Next, you used a rather imprecise wall-clock timer to time your performance. 接下来,您使用了一个不太精确的挂钟计时器来计时您的演奏。 datetime.now() is fine for humans that want to know the current time, it is not fine for measuring performance. datetime.now()对于想知道当前时间的人来说是不错的选择,而对于衡量性能来说则不合适。 There are better, more specialised clocks available to Python for the latter task. 对于后者,Python有更好,更专业的时钟可用。 Python itself also has a background process called the garbage collector that'll also want to get some time to do its work, affecting how Python performs the tasks you gave it. Python本身也有一个称为垃圾收集器的后台进程,该进程还将希望花一些时间来完成其工作,从而影响Python执行给它的任务的方式。

Instead, you need to separate out different problems that Python has to solve here into separate tests. 相反,您需要将Python必须在此处解决的不同问题分开进行单独的测试。 Run those separate tests under controlled circumstances, with an accurate clock, and with as many distractions as possible disabled. 在受控的情况下,使用准确的时钟并在尽可能多的干扰下禁用它们,来运行这些单独的测试。 Run those tests many, many times and then take either an average time (if you only have an aggregate available) or the best time from many repeats. 多次运行这些测试然后花费平均时间(如果您只有可用的汇总)或多次重复的最佳时间。

Python has a library for this, called timeit . Python为此提供了一个库,称为timeit Use that to only create the instances, not store them all in a dictionary too. 使用它创建实例,也不将其全部存储在字典中。 As stated before, memory allocation is subject to the OS's timings, not Python's. 如前所述,内存分配取决于操作系统的时间,而不是Python的时间。 Make sure to keep repeating your tests; 确保继续重复测试; if -m timeit runs a test just once you really can't trust the timings, reduce the work done in the benchmark. 如果-m timeit您真的不信任计时-m timeit运行测试,请减少基准测试中完成的工作。

Next, if your goal is to compare Python 3.6 vs 3.7 on general performance terms and not a specific microbenchmark, then you'll need to a wide range of tests. 接下来,如果您的目标是按照常规性能而非特定的微基准来比较Python 3.6与3.7,那么您将需要进行广泛的测试。 Stuff changes all the time from 3.x to 3.x+1 releases. Stuff始终从3.x更改为3.x + 1版本。 Don't base anything on a single string join or instance creation test. 不要以单个字符串连接或实例创建测试为基础。 And know that the Python developers will already have done all that work. 并且知道Python开发人员已经完成了所有工作。 See 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 for another such benchmark. 请参阅https://speed.python.org/以获取核心团队用来监视性能的全套基准测试和计时,或参阅PyPerformance套件以获取另一种此类基准。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM