Python 多处理队列:执行 get() 是瓶颈

问题描述 投票:0回答:1

我用 Python 创建事件生成器。

我有3个模块(每个模块都是一个单独的

Process
):

  • 输入模块:在不同时刻唤醒,然后将时刻的时间戳放入
    Input Queue
  • 事件模块:从
    Input Queue
    获取时间戳,使用该时间戳渲染事件并将其发送到
    Event Queue
  • 输出模块:从
    Event Queue
    获取渲染事件并将其写入某个端点;

高EPS值的性能问题在事件模块

问题是

Queue.get()
调用消耗了最多的执行时间。
Input Queue
已提前填充,因此
Input Queue
始终可用于执行以下示例中的 get 操作。

这是一些带有性能分析的简化代码:


spent_on_render = 0.0
spent_on_putting = 0.0
spent_on_getting = 0.0
spent_summary = 0.0

events_batch = []
last_flush = perf_counter()

while True:
    start = perf_counter()

    if (
        len(events_batch) >= FLUSH_AFTER_SIZE
        or (perf_counter() - last_flush) > FLUSH_AFTER_SECONDS
    ):
        putting_time = perf_counter()

        for event in events_batch:
            event_queue.put(event)

        spent_on_putting += perf_counter() - putting_time

        events_batch.clear()
        last_flush = perf_counter()

    try:
        get_time = perf_counter()
        timestamp = input_queue.get(
            block=False,
            timeout=0
        )
        spent_on_getting += perf_counter() - get_time
    except Empty:
        spent_summary += perf_counter() - start
        continue

    render_time = perf_counter()
    events_batch.append(event_plugin.produce(timestamp=timestamp))
    spent_on_render += perf_counter() - render_time
    

    spent_summary += perf_counter() - start

一段时间的执行结果如下:

=================================
Spent on render: 12.241767558232823
Spent on putting: 0.326323675999447
Spent on getting: 22.14875863072848
Spent summary: 35.32571034637658

令我困惑的时刻是,如果我只是循环地从队列中获取而不进行任何其他操作,那么从队列中读取相同数量的时间戳的时间会减少很多倍。

那么在所描述的情况下我可以做什么来破坏性能或者我应该在我的情况下使用不同的 IPC 方式?


更新:

这里有一些额外的研究: 当我第一次读取所有输入队列然后将其放入下一个队列时:

timestamps = []
start = perf_counter()
qsize = input_queue.qsize()
for _ in range(qsize):
    timestamps.append(input_queue.get())

print('Size:', qsize)
print('Time spent after get:', perf_counter() - start)

for ts in timestamps:
    event_queue.put(ts)

print('Time spent after put:', perf_counter() - start)

输出是:

Size: 1000000
Time spent after get: 1.935170126002049
Time spent after put: 2.2695002569998906

当我读取元素并在同一迭代中将其放入下一个队列时:

start = perf_counter()
qsize = input_queue.qsize()
for _ in range(qsize):
    ts = input_queue.get()
    event_queue.put(ts)

print('Size:', qsize)
print('Time spent after get and put:', perf_counter() - start)

输出是:

Size: 1000000
Time spent after get and put: 16.109829995999462

为什么差别这么大?

python performance multiprocessing queue ipc
1个回答
0
投票

问题与上下文切换有关。我为批量大小设置了更大的值并获得了所需的性能。

© www.soinside.com 2019 - 2024. All rights reserved.