加快循环以更新对象列表

时间:2016-10-31 14:20:01

标签: python performance bokeh

我想尽快更新python中的对象列表。我现在正在做的将在以下代码中演示:

from bokeh.models.sources import ColumnDataSource
from random import randint

n = 10
m = 50
sources = []
for i in range(n):
    # all list elements have similar structure
    sources.append(ColumnDataSource(data=dict(x=range(m), y=range(m), count=[0])))

def some_function():
    # do some computation
    return [randint(0, m) for i in xrange(n)]

def update():
    # this function is called every 20ms
    for s in sources:
        s.data = dict(x=some_function(), y=s.data['y'], count=[s.data['count'][0]+1])

我的 update()函数的for循环耗时太长。我有很多要更新的列表,每20 ms调用一次该函数。有时 update()函数执行时间超过20毫秒。

从我目前的研究中我知道列表推导比循环快得多,但我不能在我的情况下使用它们,可以吗?像:

#not working code
sources = [dict(x=.., y=.., count=..) for s.data in sources]

3 个答案:

答案 0 :(得分:0)

不确定它会更快但你可以。

sources = [ColumnDataSource(data=dict(x=some_function(), y=s.data['y'], count=[s.data['count'][0] + 1]) for s in sources]

如果必须保留相同的对象,它将无法工作。

答案 1 :(得分:0)

您可以对初始for循环和更新函数使用list comprehension。

循环的首字母:

sources = [ColumnDataSource(data=dict(x=range(m), y=range(m), count=[0]) for i in range(n)]

更新循环:

s_updated = [ColumnDataSource(data=dict(x=some_function(), y=s.data['y'], count=[s.data['count'][0]+1])) for s in sources]

答案 2 :(得分:0)

使用{'key': 'value, ...}表示法初始化词典比使用dict()更快,所以我会使用它:

timeit.timeit('{"a": 1, "b": 2}', number=1000000)
0.1645284985700215

timeit.timeit('dict(a=1, b=2)', number=1000000)
0.4730025877568096

这给出了:

def update():
    # this function is called every 20ms
    for s in sources:
        s.data = {'x': some_function(), 'y': s.data['y'], 'count': [s.data['count'][0]+1]}

而且BTW为什么这"计算"一个列表 ?一个整数就足够了。