我用 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
为什么差别这么大?
问题与上下文切换有关。我为批量大小设置了更大的值并获得了所需的性能。