在多处理中datetime.datetime.now的性能

时间:2015-07-28 18:13:02

标签: python multiprocessing

在使用python多处理编写一些并行代码时,我注意到在我的Mac笔记本电脑和Windows服务器机器上运行代码之间存在奇怪的性能行为差异。当我连续运行代码时,Mac笔记本电脑的速度是Windows机器的两倍,但是当运行2个内核时速度是后者的两倍,并且它的性能因更多内核(仍然在核心总数下)而稳定,而Windows机器表现得体面。

使用cProfile,我意识到使用多个内核,Mac使用以下上下文管理器几乎花费所有时间调用datetime.datetime.now,用于执行一些内部计时:

class timer:
    def __init__(self):
        self.timer = datetime.datetime.now

    def __enter__(self):
        self.start = self.timer()
        return self

    def __exit__(self, *arg):
        self.end = self.timer()
        self.elapsed = (self.end - self.start) 

使用类似的东西:

with timer() as t:
    <run some code>
total_time += t.elapsed

当我将代码修改为不调用datetime.datetime.now并设置self.elapsed = datetime.timedelta(0)时,我会恢复正确的并行缩放。

我在Windows下没有看到这种行为,所以我想知道为什么OSX会在多个进程中调用now()时遇到性能损失。调用程序的两个串行实例不会导致一个进程影响另一个进程,而不是单个串行运行。

有没有人对此行为有解释?我在两台机器上都使用Python 2.7.10。

1 个答案:

答案 0 :(得分:0)

This question可能会给出解释。

我的猜测是MAC OS不允许对实时时钟进行并发读访问。因此,当时只有一个进程可以读取该值,从而大大降低了性能。

要验证上述链接中给出的答案,您可以在读取时间时检查进程是否实际暂停IO等待。只生成大量进程,只读取时间并检查它们是否在IO等待中暂停。