线程未与ThreadPoolExecutor在python中并行执行
我是python线程方面的新手,我正在尝试: 当我在线程中运行某些东西时(每当我打印输出时),它似乎永远不会并行运行。此外,我的函数使用的时间与使用库concurrent.futures(ThreadPoolExecutor)之前相同。 我必须计算数据集上某些属性的增益(我不能使用库)。由于我有大约1024个属性,并且函数执行大约需要一分钟(我必须在for迭代中使用它),因此我决定将线程未与ThreadPoolExecutor在python中并行执行,python,machine-learning,concurrency,python-multithreading,Python,Machine Learning,Concurrency,Python Multithreading,我是python线程方面的新手,我正在尝试: 当我在线程中运行某些东西时(每当我打印输出时),它似乎永远不会并行运行。此外,我的函数使用的时间与使用库concurrent.futures(ThreadPoolExecutor)之前相同。 我必须计算数据集上某些属性的增益(我不能使用库)。由于我有大约1024个属性,并且函数执行大约需要一分钟(我必须在for迭代中使用它),因此我决定将属性数组拆分为10个(作为一个示例),并为每个子数组分别运行separet函数增益(属性)。因此,我做了以下工作(
属性数组
拆分为10个(作为一个示例),并为每个子数组分别运行separet函数增益(属性)
。因此,我做了以下工作(避免了一些额外的不必要的代码):
以下是“计算收益”辅助程序:
def calculate_gains_helper(self, attributes):
inter_result = {}
for attribute in attributes:
inter_result[attribute] = self.gain(attribute)
return inter_result
我做错什么了吗?我读了其他一些老帖子,但我没有得到任何信息。
非常感谢你的帮助 Python线程不会并行运行(至少在CPython实现中),因为。使用进程并真正实现并行性 以concurrent.futures.ProcessPoolExecutor()作为执行器的
:
...
您提交并连续等待每个工作项,因此线程所做的一切都会减慢速度。我不能保证这将大大加快速度,因为您仍然在处理python GIL,它使python级别的东西无法并行工作,但现在开始
我已经创建了一个线程池,并将所有可能的内容都推送到worker中,包括对self.attributes
的切片
def calculate_gains(self):
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
result_list = executor.map(self.calculate_gains_helper,
((i, i+10) for i in range(0, len(self.attributes), 10)))
for return_value in result_list:
self.gains = {**self.gains, **return_value}
def calculate_gains_helper(self, start_end):
start, end = start_end
inter_result = {}
for attribute in self.attributes[start:end]:
inter_result[attribute] = self.gain(attribute)
return inter_result
我尝试更改为
ProcessPoolExecutor
,但现在时间更长了。@LeandroD。你在windows上吗?进程池执行器最终可能会将数组复制到子进程,这会浪费比在子进程中获得的时间更多的时间。不,我使用的是Mac OS,您只能在释放python全局解释器锁的numpy操作中获得并行性。这些计算是否可以在numpy intead内完成,而不必将其分解为python for循环?对于拆分属性中的ATT:
您正在创建一个线程执行器,提交单个工作项,然后等待for循环中每个ATT
完成。这比单线程计算要昂贵得多。您应该创建一次执行器,并将所有作业都扔给它。这很有意义!但是我该怎么做呢?我怎样才能管理所有的退货?首先感谢您的回复!我正试图弄明白你在第3行和第4行中的意思,因为这两行没有编译:(.我使用的是Python 3.7.Oops,缺少一些参数。想法是将想要的范围传递给工作线程,让它与其他线程并行进行拆分。我认为这是可行的,但执行时间没有提高:)如果有人有什么建议,我很想听听!。
def calculate_gains(self):
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
result_list = executor.map(self.calculate_gains_helper,
((i, i+10) for i in range(0, len(self.attributes), 10)))
for return_value in result_list:
self.gains = {**self.gains, **return_value}
def calculate_gains_helper(self, start_end):
start, end = start_end
inter_result = {}
for attribute in self.attributes[start:end]:
inter_result[attribute] = self.gain(attribute)
return inter_result