python - 多线程和单线程在 Python 中提供相同的性能
问题描述
在下面的代码中,如果我注释“第 6 行”并取消注释“第 3、4、5 行”。代码在主线程中运行,耗时 17 秒。
现在,如果我取消注释“第 6 行”并注释“第 3、4、5 行”。取消注释“第 1 行”并注释“第 2 行”,然后代码在多线程(创建 3 个线程)中运行,所用时间再次为 17 秒。所以多线程和单线程需要相同的时间。
现在,如果我取消注释“第 6 行”并注释“第 3、4、5 行”。并注释“第 1 行”并取消注释“第 2 行”,然后代码在多进程中运行(创建 3 个进程)所用时间为 9 秒。与单步和多步相比,多处理的工作速度更快。
请让我们知道为什么多线程性能与单线程相同?
import threading
import time
import multiprocessing
import multiprocessing.pool
class xyz:
def __init__(self):
self.data = []
pass
def loopData(self):
item = range(0, 100000000)
for i in item:
self.data.append(i)
def loopDatamulti(self):
num_of_thread = 3
thread_list = []
while True:
t = threading.Thread(target=self.loopData, args=()) #line 1
#t = multiprocessing.Process(target=self.loopData,args=()) #line 2
thread_list.append(t)
num_of_thread_created = len(thread_list)
if num_of_thread_created == num_of_thread:
break
for t in thread_list:
t.start()
for t in thread_list:
t.join()
def main():
print("Start")
start_time = time.time()
xa = xyz()
#xa.loopData() #line 3
#xa.loopData() #line 4
#xa.loopData() #line 5
xa.loopDatamulti() #line 6
end_time = time.time()
strLog = "total time {}".format(end_time - start_time)
print(strLog)
if __name__ == "__main__":
main()
解决方案
多线程不太适合执行纯 CPU 密集型的函数。如果这些函数永远不会产生 CPU(例如,对于某种 I/O),它们只会“锁定”单个 CPU,您将不会获得任何好处。这就是多处理发挥作用的地方。即使这样,您也需要小心,因为如果您的函数是短暂的,那么创建单独进程的开销可能会超过您可能期望的优势。这是一个多处理的例子。使用变量 ITERS 和 PROCS 看看行为如何变化,你就会明白这一点。函数 (myFunc) 只是执行任意伪随机计算并构建一个列表以返回。
from datetime import datetime
from multiprocessing import Pool
import math
import random
ITERS = 100_000
PROCS = 100
def myFunc(r):
return [(math.sqrt(random.randint(1, 2000))**2)**(1 / 3) for _ in range(r)]
if __name__ == '__main__':
_start = datetime.now()
with Pool() as pool:
for p in [pool.apply_async(func=myFunc, args=(ITERS,))
for _ in range(PROCS)]:
p.wait()
_end = datetime.now()
print(f'Multi-processing duration={_end-_start}')
_start = datetime.now()
for I in range(PROCS):
myFunc(ITERS)
_end = datetime.now()
print(f'Single-threaded duration={_end-_start}')
在我的机器上,使用代码中显示的 ITERS 和 PROCS 的值,输出如下:-
多处理时长=0:00:01.526478
单线程时长=0:00:09.776963
推荐阅读
- reactjs - 使用 useRef 挂钩获取对 React 组件的引用
- php - Multiple Array "Merge" into 1 with different structure
- laravel - Laravel Route::resource 无法正常工作
- android - 在方法中声明最终的静态布尔变量
- asp.net - NLog 没有在 AWS ec2 Linux 中创建日志文件
- python - 如何为 Scrapy 请求添加默认 errback
- sql - 计算所有值,即使它们是重复的
- reactjs - React 应该是怎样的功能
- python - 如何在熊猫中按函数获取平均值
- python - 现在获得UTC的非天真(感知)日期时间的最简单方法是什么?