在python中使用多线程技术提高执行时间



如何实现多线程以加快进程?该程序生成100万个随机数并将其写入一个文件。它只需要2秒多,但我想知道多线程是否会让它更快。

import random
import time
startTime = time.time()
data = open("file2.txt", "a+")
for i in range(1000000):
number = str(random.randint(1, 9999))
data.write(number + 'n')
data.close()
executionTime = (time.time() - startTime)
print('Execution time in seconds: ', + str(executionTime))

简短的回答是:不容易。

下面是一个使用多处理池来加速代码的示例:

import random
import time
from multiprocessing import Pool
startTime = time.time()
def f(_):
number = str(random.randint(1, 9999))
data.write(number + 'n')
data = open("file2.txt", "a+")
with Pool() as p:
p.map(f, range(1000000))
data.close()
executionTime = (time.time() - startTime)
print(f'Execution time in seconds: {executionTime})')

看起来不错吗?等待这不是一个临时替换,因为它缺乏进程的同步性,所以不是所有1000000行都会被写入(有些会被覆盖在同一缓冲区中(!查看Python多处理安全写入文件

因此,我们需要将计算数字(并行(与编写数字(串行(分开。我们可以这样做:

import random
import time
from multiprocessing import Pool
startTime = time.time()
def f(_):
return str(random.randint(1, 9999))
with Pool() as p:
output = p.map(f, range(1000000))
with open("file2.txt", "a+") as data:
data.write('n'.join(output) + 'n')
executionTime = (time.time() - startTime)
print(f'Execution time in seconds: {executionTime})')

修复后,请注意这不是多线程,而是使用多个进程。您可以使用不同的池对象将其更改为多线程:

from multiprocessing.pool import ThreadPool as Pool

在我的系统上,处理池的时间从1秒到0.35秒。然而,使用ThreadPool最多需要2秒!

原因是Python的全局解释器锁阻止多个线程有效地处理您的任务,请参阅CPython中的全局解释器锁定(GIL(是什么?

总之,多线程并不总是正确的答案:

  1. 在您的场景中,一个限制是文件访问,只有一个线程可以写入文件,或者您需要引入锁定,使任何性能提升都变得毫无意义
  2. 此外,在Python中,多线程只适用于特定任务,例如发生在Python下面的库中的长计算,因此可以并行运行。在您的场景中,多线程的开销抵消了性能优势的微小潜力

好处是:是的,使用多处理而不是多线程,我的系统速度提高了3倍。

将字符串@写入文件一次,而不是单独将每个数字写入文件&我已经用multithreading测试了它,它实际上降低了性能,因为您在向同一文件写入时,如果执行线程,您还必须同步这将影响性能

代码:(执行时间(秒(:1.943817138671875(

import time
startTime = time.time()
import random
size = 1000_000
# pre declaring the list to save time from resize it later
l = [None] * size
# l = list(str(random.randint(1, 99999)) for i in range(size))
# random.randrange(0, )
for i in range(size):
# l[i] = str(random.randint(1, 99999)) + "n"
l[i] = f"{random.randint(1, 99999)}n"

# writing data @ once to the file
with open('file2.txt', 'w+') as data:
data.write(''.join(l))
executionTime = (time.time() - startTime)
print('Execution time in seconds: ' + str(executionTime))

输出:

Execution time in seconds: 1.943817138671875

最新更新