我有一段代码获取输入并检查输入是否符合要求。输入由名为S
的对象组成
class S:
def __init__(self, f, t, tf, timeline):
self.f = f
self.t = t
self.tf = tf
self.timeline = timeline
为了知道对象的组合是否满足要求,我让函数取对象大小的list
,并返回True
或False
input1 = [S_1, ..., S_N]
def c1(input1):
if condition_c1_valid:
return True
else:
return False
现在让我们来看这个例子:
import itertools
possible_objects = [S(f, t, tf, timeline) for f in [...] for t in [..] ...]
inputs_to_check = list(itertools.combination_with_replacement(possible_objects, 5)
results = list()
for inp in inputs_to_check:
if c1(inp):
results.append(inp)
现在,我的解决方案是在每次检查的N
条件上使用for
循环。
代码保留满足条件的输入
是否可以以矩阵方式立即计算?(矢量化)
我在想这样的事情:(伪代码)
Data[input, c1, ..., cN]
return where(all(c1, ..., cN) is True)
有谁能告诉我这是否可行,并给我举个例子吗?最后,我要检查的输入列表非常大。因此,将计算结果发送到GPU是很有趣的。我想也许这可以通过张量流来实现
谢谢你的提示:)
编辑:上面的例子与现实相去甚远。我在一个大的set
上使用嵌套的for
循环,复杂度为6级或7级。目前的解决方案是优化发电机,但我想进一步推动这一点
在最普遍的意义上,你将无法将其矢量化。由于GIL,CPython在并行处理方面是出了名的糟糕,它的主要矩阵向量化库(numpy)用于处理主要类型(整数、浮点等),而不是python对象,如
S
有几件事可以帮上忙:
如果
f
、t
、tf
、timeline
是数字(它们看起来像 可能是),然后您可以形成这些值的四个numpy数组 通过c1
的矢量化版本传递这些值,该版本返回一个布尔数组。然后你可以做np.asarray(input1)[c1_vec(f_vec, t_vec, tf_vec, timeline_vec)]
您说过您使用了生成器而不是列表,但只是为了确保您的示例应该如下所示:
possible_objects = (S(f, t, tf, timeline) for f in (...) for t in (...) ...) inputs_to_check = itertools.combination_with_replacement(possible_objects, 5) results = [inp for inp in inputs_to_check if c1(inp)]
这节省了大量将对象写入内存的时间,这是可以避免的
使用PyPy。它使用JIT编译器大大加快python for循环的速度。对于非常大的环路,这将达到接近C的速度
你提到使用GPU。CPython甚至不能在一个以上的CPU核上运行,除非使用另一个实现,否则在GPU上运行它是毫无意义的
相关问题 更多 >
编程相关推荐