我在处理多处理时编写了这个简单的代码。
from multiprocessing import Process, cpu_count
import time
def counter(num):
count = 0
while count < num:
count += 1
def main():
print(cpu_count())
a = Process(target=counter, args=(250000000,))
b = Process(target=counter, args=(250000000,))
c = Process(target=counter, args=(250000000,))
d = Process(target=counter, args=(250000000,))
a.start()
b.start()
c.start()
d.start()
a.join()
b.join()
c.join()
d.join()
print("Finished in:", time.perf_counter(), "seconds")
if __name__ == "__main__":
main()
嗯,我的代码中的所有内容都运行得很完美,除了
time.perf_counter()
为一个几乎只花了 2-3 秒的程序提供了 7000 秒的时间。我尝试使用
time.perf_counter_ns()
但它没有达到我的预期。首先,它给了我科学形式的值,当我将纳秒转换为秒时,它仍然给了我与之前相同的结果。而不是那些,我尝试使用 timeit 模块打印
timeit.timeit()
,它确实给了我像 0.0143249234 这样的值,用于一个花费超过 2 秒的程序。当我打印 cpu_cores 而不是显示我的电脑有多少个核心时,它确实给了我这个
<bound method BaseContext.cpu_count of <multiprocessing.context.DefaultContext object at 0x000001B68DDCD1C0>>
代码中出现奇怪的时间测量结果是因为你误解了
cpu_count()
的使用方式以及
time.perf_counter()
的行为。让我们来分解一下:
问题 1:
cpu_count()
的误用
-
你正在将
cpu_count()
作为一个可调用对象打印出来,而不是调用它。这就是为什么你会看到<bound method...>
的输出。为了获得 CPU 核心数量,你应该调用该函数:
python
print(cpu_count()) # 正确调用函数
问题 2:
time.perf_counter()
的范围
-
time.perf_counter()
测量的是自某个未定义的时间点以来经过的总时间,包括你的 Python 进程休眠的时间。当你启动一个进程时,time.perf_counter()
已经开始计时,它会持续计时,即使你的进程没有在执行任何操作。 -
在你的代码中,你正在你的
main()
函数中启动time.perf_counter()
,然后启动你的进程。当你的进程在后台运行时,main()
函数会立即完成,而time.perf_counter()
则会继续计时。这意味着time.perf_counter()
捕获的时间不仅包括你的进程的执行时间,还包括main()
函数完成到你的进程完成之间的时间。
解决方案
为了准确测量你的多进程代码的执行时间,你需要在启动你的进程之前和之后立即调用
time.perf_counter()
:
import multiprocessing
import time
def counter(num):
count = 0
while count < num:
count += 1
def main():
num_cores = multiprocessing.cpu_count()
print("CPU 核心数量:", num_cores)
start_time = time.perf_counter() # 在启动进程之前开始计时
a = multiprocessing.Process(target=counter, args=(250000000,))
b = multiprocessing.Process(target=counter, args=(250000000,))
c = multiprocessing.Process(target=counter, args=(250000000,))
d = multiprocessing.Process(target=counter, args=(250000000,))
a.start()
b.start()
c.start()
d.start()
a.join()
b.join()
c.join()
d.join()
end_time = time.perf_counter() # 在进程完成后停止计时
print("完成时间:", end_time - start_time, "秒")
if __name__ == "__main__":
main()
通过这种方式,你将只测量你的进程实际运行所花费的时间。
标签:python,time,multiprocessing,performancecounter,timeit From: 78798476